evolution-data-server r9483 - in branches/EXCHANGE_MAPI_BRANCH: addressbook addressbook/backends/mapi addressbook/libedata-book calendar/backends/mapi camel/providers/mapi servers/mapi
- From: msuman svn gnome org
- To: svn-commits-list gnome org
- Subject: evolution-data-server r9483 - in branches/EXCHANGE_MAPI_BRANCH: addressbook addressbook/backends/mapi addressbook/libedata-book calendar/backends/mapi camel/providers/mapi servers/mapi
- Date: Fri, 5 Sep 2008 05:54:08 +0000 (UTC)
Author: msuman
Date: Fri Sep 5 05:54:08 2008
New Revision: 9483
URL: http://svn.gnome.org/viewvc/evolution-data-server?rev=9483&view=rev
Log:
MAPI - Support for recurring appointments. Create/Modify all/Delete operations are supported. Modify single instance is not implemented.
Modified:
branches/EXCHANGE_MAPI_BRANCH/addressbook/ChangeLog
branches/EXCHANGE_MAPI_BRANCH/addressbook/backends/mapi/ChangeLog
branches/EXCHANGE_MAPI_BRANCH/addressbook/backends/mapi/e-book-backend-mapi.c
branches/EXCHANGE_MAPI_BRANCH/addressbook/libedata-book/e-book-backend-db-cache.h
branches/EXCHANGE_MAPI_BRANCH/calendar/backends/mapi/ChangeLog
branches/EXCHANGE_MAPI_BRANCH/calendar/backends/mapi/e-cal-backend-mapi.c
branches/EXCHANGE_MAPI_BRANCH/camel/providers/mapi/ChangeLog
branches/EXCHANGE_MAPI_BRANCH/camel/providers/mapi/camel-mapi-folder.c
branches/EXCHANGE_MAPI_BRANCH/servers/mapi/ChangeLog
branches/EXCHANGE_MAPI_BRANCH/servers/mapi/Makefile.am
branches/EXCHANGE_MAPI_BRANCH/servers/mapi/exchange-mapi-cal-recur-utils.c
branches/EXCHANGE_MAPI_BRANCH/servers/mapi/exchange-mapi-cal-recur-utils.h
branches/EXCHANGE_MAPI_BRANCH/servers/mapi/exchange-mapi-cal-tz-utils.h
branches/EXCHANGE_MAPI_BRANCH/servers/mapi/exchange-mapi-cal-utils.c
branches/EXCHANGE_MAPI_BRANCH/servers/mapi/exchange-mapi-cal-utils.h
branches/EXCHANGE_MAPI_BRANCH/servers/mapi/exchange-mapi-connection.c
branches/EXCHANGE_MAPI_BRANCH/servers/mapi/exchange-mapi-connection.h
branches/EXCHANGE_MAPI_BRANCH/servers/mapi/exchange-mapi-defs.h
Modified: branches/EXCHANGE_MAPI_BRANCH/addressbook/backends/mapi/e-book-backend-mapi.c
==============================================================================
--- branches/EXCHANGE_MAPI_BRANCH/addressbook/backends/mapi/e-book-backend-mapi.c (original)
+++ branches/EXCHANGE_MAPI_BRANCH/addressbook/backends/mapi/e-book-backend-mapi.c Fri Sep 5 05:54:08 2008
@@ -641,7 +641,7 @@
exchange_mapi_util_mapi_ids_from_uid (tmp, &fid, &mid);
printf("modify id %s\n", tmp);
- status = exchange_mapi_modify_item (olFolderContacts, priv->fid, mid, mapi_book_build_name_id, contact, mapi_book_build_props, contact, NULL, NULL, 0);
+ status = exchange_mapi_modify_item (olFolderContacts, priv->fid, mid, mapi_book_build_name_id, contact, mapi_book_build_props, contact, NULL, NULL, NULL, 0);
printf("getting %016llX\n", status);
if (!status) {
e_data_book_respond_modify(book, opid, GNOME_Evolution_Addressbook_OtherError, NULL);
Modified: branches/EXCHANGE_MAPI_BRANCH/addressbook/libedata-book/e-book-backend-db-cache.h
==============================================================================
--- branches/EXCHANGE_MAPI_BRANCH/addressbook/libedata-book/e-book-backend-db-cache.h (original)
+++ branches/EXCHANGE_MAPI_BRANCH/addressbook/libedata-book/e-book-backend-db-cache.h Fri Sep 5 05:54:08 2008
@@ -25,6 +25,8 @@
#include <libebook/e-contact.h>
#include "db.h"
+G_BEGIN_DECLS
+
EContact* e_book_backend_db_cache_get_contact (DB *db, const char *uid);
void string_to_dbt(const char *str, DBT *dbt);
char *e_book_backend_db_cache_get_filename(DB *db);
@@ -39,9 +41,8 @@
void e_book_backend_db_cache_set_populated (DB *db);
gboolean e_book_backend_db_cache_is_populated (DB *db);
GPtrArray* e_book_backend_db_cache_search (DB *db, const char *query);
-
-
-
+void e_book_backend_db_cache_set_time(DB *db, const char *t);
+char * e_book_backend_db_cache_get_time (DB *db);
G_END_DECLS
Modified: branches/EXCHANGE_MAPI_BRANCH/calendar/backends/mapi/e-cal-backend-mapi.c
==============================================================================
--- branches/EXCHANGE_MAPI_BRANCH/calendar/backends/mapi/e-cal-backend-mapi.c (original)
+++ branches/EXCHANGE_MAPI_BRANCH/calendar/backends/mapi/e-cal-backend-mapi.c Fri Sep 5 05:54:08 2008
@@ -365,17 +365,6 @@
// exchange_mapi_debug_property_dump (array);
recurring = NULL;
- /* FIXME: Provide backend support for recurrence for appointments/meetings */
- recurring = (const bool *)find_mapi_SPropValue_data(array, PROP_TAG(PT_BOOLEAN, 0x8223));
- if (recurring && *recurring) {
- g_warning ("Encountered a recurring event.");
- exchange_mapi_util_free_stream_list (&streams);
- exchange_mapi_util_free_recipient_list (&recipients);
- exchange_mapi_util_free_attachment_list (&attachments);
- return TRUE;
- }
-
- recurring = NULL;
/* FIXME: Evolution does not support recurring tasks */
recurring = (const bool *)find_mapi_SPropValue_data(array, PROP_TAG(PT_BOOLEAN, 0x8126));
if (recurring && *recurring) {
@@ -846,17 +835,6 @@
// exchange_mapi_debug_property_dump (properties);
switch (kind) {
- case ICAL_VEVENT_COMPONENT:
- /* FIXME: Provide backend support for recurrence */
- recurring = (const bool *)find_mapi_SPropValue_data(properties, PROP_TAG(PT_BOOLEAN, 0x8223));
- if (recurring && *recurring) {
- g_warning ("Encountered a recurring event.");
- exchange_mapi_util_free_stream_list (&streams);
- exchange_mapi_util_free_recipient_list (&recipients);
- exchange_mapi_util_free_attachment_list (&attachments);
- return TRUE;
- }
- break;
case ICAL_VTODO_COMPONENT:
/* FIXME: Evolution does not support recurring tasks */
recurring = (const bool *)find_mapi_SPropValue_data(properties, PROP_TAG(PT_BOOLEAN, 0x8126));
@@ -868,6 +846,7 @@
return TRUE;
}
break;
+ case ICAL_VEVENT_COMPONENT :
case ICAL_VJOURNAL_COMPONENT:
break;
default:
@@ -1263,6 +1242,7 @@
gchar *tmp = NULL;
GSList *recipients = NULL;
GSList *attachments = NULL;
+ GSList *streams = NULL;
struct cbdata cbdata;
struct SBinary globalid;
@@ -1289,10 +1269,19 @@
comp = e_cal_component_new ();
e_cal_component_set_icalcomponent (comp, icalcomp);
- /* FIXME: Add support for recurrences */
+ /* FIXME: [WIP] Add support for recurrences */
if (e_cal_component_has_recurrences (comp)) {
- g_object_unref (comp);
- return GNOME_Evolution_Calendar_OtherError;
+ GByteArray *ba = exchange_mapi_cal_util_rrule_to_bin (comp, NULL);
+ if (ba) {
+ struct SPropTagArray *tag_array;
+ ExchangeMAPIStream *stream = g_new0 (ExchangeMAPIStream, 1);
+ stream->value = ba;
+ tag_array = exchange_mapi_util_resolve_named_prop (priv->olFolder, priv->fid, 0x8216, PSETID_Appointment);
+ if (tag_array) {
+ stream->proptag = tag_array->aulPropTag[0];
+ streams = g_slist_append (streams, stream);
+ }
+ }
}
/* FIXME: [WIP] Add support for meetings/assigned tasks */
@@ -1329,12 +1318,13 @@
mid = exchange_mapi_create_item (priv->olFolder, priv->fid,
exchange_mapi_cal_util_build_name_id, GINT_TO_POINTER(kind),
exchange_mapi_cal_util_build_props, &cbdata,
- recipients, attachments, NULL, MAPI_OPTIONS_DONT_SUBMIT);
+ recipients, attachments, streams, MAPI_OPTIONS_DONT_SUBMIT);
g_free (cbdata.props);
// g_free (globalid.lpb);
if (!mid) {
g_object_unref (comp);
exchange_mapi_util_free_recipient_list (&recipients);
+ exchange_mapi_util_free_stream_list (&streams);
exchange_mapi_util_free_attachment_list (&attachments);
return GNOME_Evolution_Calendar_OtherError;
}
@@ -1350,6 +1340,7 @@
break;
default:
exchange_mapi_util_free_recipient_list (&recipients);
+ exchange_mapi_util_free_stream_list (&streams);
exchange_mapi_util_free_attachment_list (&attachments);
return GNOME_Evolution_Calendar_CalListener_MODE_NOT_SUPPORTED;
}
@@ -1360,6 +1351,7 @@
g_object_unref (comp);
exchange_mapi_util_free_recipient_list (&recipients);
+ exchange_mapi_util_free_stream_list (&streams);
exchange_mapi_util_free_attachment_list (&attachments);
return GNOME_Evolution_Calendar_Success;
@@ -1432,6 +1424,7 @@
mapi_id_t mid;
const char *uid = NULL, *rid = NULL;
GSList *recipients = NULL;
+ GSList *streams = NULL;
GSList *attachments = NULL;
struct cbdata cbdata;
gboolean no_increment = FALSE;
@@ -1448,6 +1441,11 @@
if (priv->mode == CAL_MODE_LOCAL)
return GNOME_Evolution_Calendar_RepositoryOffline;
+ if (mod != CALOBJ_MOD_ALL) {
+ e_cal_backend_notify_error (E_CAL_BACKEND (cbmapi), _("Support for modifying single instances of a recurring appointment is not yet implemented. No change was made to the appointment on the server."));
+ return GNOME_Evolution_Calendar_Success;
+ }
+
/* check the component for validity */
icalcomp = icalparser_parse_string (calobj);
if (!icalcomp)
@@ -1466,10 +1464,19 @@
comp = e_cal_component_new ();
e_cal_component_set_icalcomponent (comp, icalcomp);
- /* FIXME: Add support for recurrences */
+ /* FIXME: [WIP] Add support for recurrences */
if (e_cal_component_has_recurrences (comp)) {
- g_object_unref (comp);
- return GNOME_Evolution_Calendar_OtherError;
+ GByteArray *ba = exchange_mapi_cal_util_rrule_to_bin (comp, NULL);
+ if (ba) {
+ struct SPropTagArray *tag_array;
+ ExchangeMAPIStream *stream = g_new0 (ExchangeMAPIStream, 1);
+ stream->value = ba;
+ tag_array = exchange_mapi_util_resolve_named_prop (priv->olFolder, priv->fid, 0x8216, PSETID_Appointment);
+ if (tag_array) {
+ stream->proptag = tag_array->aulPropTag[0];
+ streams = g_slist_append (streams, stream);
+ }
+ }
}
if (e_cal_component_has_attendees (comp))
@@ -1479,7 +1486,7 @@
exchange_mapi_cal_util_fetch_attachments (comp, &attachments, priv->local_attachments_store);
e_cal_component_get_uid (comp, &uid);
- rid = e_cal_component_get_recurid_as_string (comp);
+// rid = e_cal_component_get_recurid_as_string (comp);
switch (priv->mode) {
case CAL_MODE_ANY :
@@ -1495,6 +1502,7 @@
g_message ("CRITICAL : Could not find the object in cache");
g_object_unref (comp);
exchange_mapi_util_free_recipient_list (&recipients);
+ exchange_mapi_util_free_stream_list (&streams);
exchange_mapi_util_free_attachment_list (&attachments);
return GNOME_Evolution_Calendar_ObjectNotFound;
}
@@ -1524,12 +1532,13 @@
status = exchange_mapi_modify_item (priv->olFolder, priv->fid, mid,
exchange_mapi_cal_util_build_name_id, GINT_TO_POINTER(kind),
exchange_mapi_cal_util_build_props, &cbdata,
- recipients, attachments, MAPI_OPTIONS_DONT_SUBMIT);
+ recipients, attachments, streams, MAPI_OPTIONS_DONT_SUBMIT);
g_free (cbdata.props);
if (!status) {
g_object_unref (comp);
g_object_unref (cache_comp);
exchange_mapi_util_free_recipient_list (&recipients);
+ exchange_mapi_util_free_stream_list (&streams);
exchange_mapi_util_free_attachment_list (&attachments);
return GNOME_Evolution_Calendar_OtherError;
}
@@ -1538,6 +1547,7 @@
g_object_unref (comp);
g_object_unref (cache_comp);
exchange_mapi_util_free_recipient_list (&recipients);
+ exchange_mapi_util_free_stream_list (&streams);
exchange_mapi_util_free_attachment_list (&attachments);
return GNOME_Evolution_Calendar_CalListener_MODE_NOT_SUPPORTED;
}
@@ -1548,6 +1558,7 @@
g_object_unref (comp);
g_object_unref (cache_comp);
exchange_mapi_util_free_recipient_list (&recipients);
+ exchange_mapi_util_free_stream_list (&streams);
exchange_mapi_util_free_attachment_list (&attachments);
return GNOME_Evolution_Calendar_Success;
@@ -1578,7 +1589,8 @@
case CAL_MODE_ANY :
case CAL_MODE_REMOTE : /* when online, modify/delete the item from the server */
/* check if the object exists */
- status = e_cal_backend_mapi_get_object (backend, cal, uid, rid, &calobj);
+ /* FIXME: we may have detached instances which need to be removed */
+ status = e_cal_backend_mapi_get_object (backend, cal, uid, NULL, &calobj);
if (status != GNOME_Evolution_Calendar_Success)
return status;
@@ -1599,7 +1611,7 @@
time_rid = icaltime_from_string (rid);
e_cal_util_remove_instances (icalcomp, time_rid, mod);
new_calobj = (char *) icalcomponent_as_ical_string (icalcomp);
- status = e_cal_backend_mapi_modify_object (backend, cal, new_calobj, mod, &obj, &new_object);
+ status = e_cal_backend_mapi_modify_object (backend, cal, new_calobj, CALOBJ_MOD_ALL, &obj, &new_object);
if (status == GNOME_Evolution_Calendar_Success) {
*old_object = obj;
*object = new_object;
@@ -1637,10 +1649,13 @@
g_slist_free (comp_list);
}
g_free (calobj);
- return status;
+ break;
default :
- return GNOME_Evolution_Calendar_CalListener_MODE_NOT_SUPPORTED;
+ status = GNOME_Evolution_Calendar_CalListener_MODE_NOT_SUPPORTED;
+ break;
}
+
+ return status;
}
static ECalBackendSyncStatus
Modified: branches/EXCHANGE_MAPI_BRANCH/camel/providers/mapi/camel-mapi-folder.c
==============================================================================
--- branches/EXCHANGE_MAPI_BRANCH/camel/providers/mapi/camel-mapi-folder.c (original)
+++ branches/EXCHANGE_MAPI_BRANCH/camel/providers/mapi/camel-mapi-folder.c Fri Sep 5 05:54:08 2008
@@ -597,8 +597,6 @@
PR_BODY,
PR_BODY_UNICODE,
- PR_BODY_HTML,
- PR_BODY_HTML_UNICODE,
PR_DISPLAY_TO,
PR_DISPLAY_TO_UNICODE,
Modified: branches/EXCHANGE_MAPI_BRANCH/servers/mapi/Makefile.am
==============================================================================
--- branches/EXCHANGE_MAPI_BRANCH/servers/mapi/Makefile.am (original)
+++ branches/EXCHANGE_MAPI_BRANCH/servers/mapi/Makefile.am Fri Sep 5 05:54:08 2008
@@ -29,7 +29,10 @@
exchange-mapi-cal-utils.c \
exchange-mapi-cal-utils.h \
exchange-mapi-cal-tz-utils.c \
- exchange-mapi-cal-tz-utils.h
+ exchange-mapi-cal-tz-utils.h \
+ exchange-mapi-cal-recur-utils.c \
+ exchange-mapi-cal-recur-utils.h
+
libexchangemapi_1_0_la_LIBADD = \
$(E_DATA_SERVER_LIBS) \
@@ -44,7 +47,8 @@
exchange-mapi-connection.h \
exchange-mapi-utils.h \
exchange-mapi-cal-utils.h \
- exchange-mapi-cal-tz-utils.h
+ exchange-mapi-cal-tz-utils.h \
+ exchange-mapi-cal-recur-utils.h
%-1.0.pc: %.pc
cp $< $@
Modified: branches/EXCHANGE_MAPI_BRANCH/servers/mapi/exchange-mapi-cal-recur-utils.c
==============================================================================
--- branches/EXCHANGE_MAPI_BRANCH/servers/mapi/exchange-mapi-cal-recur-utils.c (original)
+++ branches/EXCHANGE_MAPI_BRANCH/servers/mapi/exchange-mapi-cal-recur-utils.c Fri Sep 5 05:54:08 2008
@@ -25,47 +25,207 @@
#include "exchange-mapi-cal-recur-utils.h"
-#define ZERO_BYTE 0x00
+/* Reader/Writer versions */
+#define READER_VERSION 0x3004
+#define WRITER_VERSION 0x3004
+#define READER_VERSION2 0x3006
+#define WRITER_VERSION2 0x3009
+
+#if 0
+struct ChangeHighlight {
+ uint32_t Size;
+ uint32_t Value;
+ uint32_t Reserved;
+};
+
+struct ExtendedException {
+ struct ChangeHighlight ch;
+ uint32_t ReservedEE1Size;
+ uint32_t ReservedEE1;
+ uint32_t StartDateTime;
+ uint32_t EndDateTime;
+ uint32_t OrigStartDate;
+ uint16_t WideCharSubjectLength;
+ gchar *WideCharSubject;
+ uint16_t WideCharLocationLength;
+ gchar *WideCharLocation;
+ uint32_t ReservedEE2Size;
+ uint32_t ReservedEE2;
+};
+
+struct ExceptionInfo {
+ uint32_t StartDateTime;
+ uint32_t EndDateTime;
+ uint32_t OrigStartDate;
+ uint16_t OverrideFlags;
+ uint16_t SubjectLength;
+ uint16_t SubjectLength2;
+ gchar *Subject;
+ uint32_t MeetingType;
+ uint32_t ReminderDelta;
+ uint32_t ReminderSet;
+ uint16_t LocationLength;
+ uint16_t LocationLength2;
+ gchar *Location;
+ uint32_t BusyStatus;
+ uint32_t Attachment;
+ uint32_t SubType;
+ uint32_t AppointmentColor;
+};
+#endif
-/* preamble */
-#define PREAMBLE 0x30043004
+static icalrecurrencetype_weekday
+get_ical_weekstart (uint32_t fdow)
+{
+ switch (fdow) {
+ case FirstDOW_Sunday : return ICAL_SUNDAY_WEEKDAY;
+ case FirstDOW_Monday : return ICAL_MONDAY_WEEKDAY;
+ case FirstDOW_Tuesday : return ICAL_TUESDAY_WEEKDAY;
+ case FirstDOW_Wednesday : return ICAL_WEDNESDAY_WEEKDAY;
+ case FirstDOW_Thursday : return ICAL_THURSDAY_WEEKDAY;
+ case FirstDOW_Friday : return ICAL_FRIDAY_WEEKDAY;
+ case FirstDOW_Saturday : return ICAL_SATURDAY_WEEKDAY;
+ default : return ICAL_SUNDAY_WEEKDAY;
+ }
+}
-/** Pattern termination **/
-#define REPEAT_UNTIL 0x00002021
-#define REPEAT_FOR_N 0x00002022
-#define REPEAT_FOREVER 0x00002023
+static uint32_t
+get_mapi_weekstart (icalrecurrencetype_weekday weekstart)
+{
+ switch (weekstart) {
+ case ICAL_SUNDAY_WEEKDAY : return FirstDOW_Sunday;
+ case ICAL_MONDAY_WEEKDAY : return FirstDOW_Monday;
+ case ICAL_TUESDAY_WEEKDAY : return FirstDOW_Tuesday;
+ case ICAL_WEDNESDAY_WEEKDAY: return FirstDOW_Wednesday;
+ case ICAL_THURSDAY_WEEKDAY : return FirstDOW_Thursday;
+ case ICAL_FRIDAY_WEEKDAY : return FirstDOW_Friday;
+ case ICAL_SATURDAY_WEEKDAY : return FirstDOW_Saturday;
+ default : return FirstDOW_Sunday;
+ }
+}
-/** Outlook version indicator (?) **/
-#define VERSION_PREAMBLE 0x00003006
-/* This version-id is equivalent to Outlook 2007 */
-#define VERSION_ID 0x00003009
+static uint32_t
+get_mapi_day (icalrecurrencetype_weekday someday)
+{
+ switch (someday) {
+ case ICAL_SUNDAY_WEEKDAY : return olSunday;
+ case ICAL_MONDAY_WEEKDAY : return olMonday;
+ case ICAL_TUESDAY_WEEKDAY : return olTuesday;
+ case ICAL_WEDNESDAY_WEEKDAY: return olWednesday;
+ case ICAL_THURSDAY_WEEKDAY : return olThursday;
+ case ICAL_FRIDAY_WEEKDAY : return olFriday;
+ case ICAL_SATURDAY_WEEKDAY : return olSaturday;
+ default : return 0;
+ }
+}
+static int32_t
+get_ical_pos (uint32_t pos)
+{
+ switch (pos) {
+ case RecurrenceN_First : return 1;
+ case RecurrenceN_Second : return 2;
+ case RecurrenceN_Third : return 3;
+ case RecurrenceN_Fourth : return 4;
+ case RecurrenceN_Last : return (-1);
+ default : return 0;
+ }
+}
-/* terminal sequence (should add twice) */
-#define TERMINAL_SEQ 0x00000000
+static uint32_t
+get_mapi_pos (int32_t pos)
+{
+ switch (pos) {
+ case 1 : return RecurrenceN_First;
+ case 2 : return RecurrenceN_Second;
+ case 3 : return RecurrenceN_Third;
+ case 4 : return RecurrenceN_Fourth;
+ case -1 : return RecurrenceN_Last;
+ default : return 0;
+ }
+}
-struct icaltimetype dt1601;
-struct icaltimetype dt1970;
+#define cFileTimeUnitsPerSecond 10000000
-static icalrecurrencetype_weekday
-get_ical_weekday (uint32_t olWeekday) {
- switch (olWeekday) {
- case olSunday:
- return ICAL_SUNDAY_WEEKDAY;
- case olMonday:
- return ICAL_MONDAY_WEEKDAY;
- case olTuesday:
- return ICAL_TUESDAY_WEEKDAY;
- case olWednesday:
- return ICAL_WEDNESDAY_WEEKDAY;
- case olThursday:
- return ICAL_THURSDAY_WEEKDAY;
- case olFriday:
- return ICAL_FRIDAY_WEEKDAY;
- case olSaturday:
- return ICAL_SATURDAY_WEEKDAY;
- default:
- return ICAL_SUNDAY_WEEKDAY;
+static void
+convert_recurrence_minutes_to_date (uint32_t minutes, struct FILETIME *ft)
+{
+ NTTIME nt;
+
+ nt = (NTTIME) minutes * (60 * cFileTimeUnitsPerSecond);
+
+ ft->dwLowDateTime = (uint32_t)((nt << 32) >> 32);
+ ft->dwHighDateTime = (uint32_t)(nt >> 32);
+}
+
+static uint32_t
+convert_date_to_recurrence_minutes (const struct FILETIME *ft)
+{
+ NTTIME minutes;
+
+ minutes = ft->dwHighDateTime;
+ minutes = minutes << 32;
+ minutes |= ft->dwLowDateTime;
+
+ minutes = minutes / (60 * cFileTimeUnitsPerSecond);
+
+ return (uint32_t)(minutes);
+}
+
+static time_t
+convert_filetime_to_timet (const struct FILETIME *ft)
+{
+ NTTIME time;
+
+ time = ft->dwHighDateTime;
+ time = time << 32;
+ time |= ft->dwLowDateTime;
+
+ return nt_time_to_unix (time);
+}
+
+static void
+convert_timet_to_filetime (time_t t, struct FILETIME *ft)
+{
+ NTTIME nt;
+
+ unix_to_nt_time (&nt, t);
+
+ ft->dwLowDateTime = (uint32_t)((nt << 32) >> 32);
+ ft->dwHighDateTime = (uint32_t)(nt >> 32);
+}
+
+static time_t
+convert_recurrence_minutes_to_timet (uint32_t minutes)
+{
+ NTTIME nt;
+
+ nt = (NTTIME) minutes * (60 * cFileTimeUnitsPerSecond);
+
+ return nt_time_to_unix (nt);
+}
+
+static uint32_t
+convert_timet_to_recurrence_minutes (time_t t)
+{
+ NTTIME minutes;
+
+ unix_to_nt_time (&minutes, t);
+
+ minutes = minutes / (60 * cFileTimeUnitsPerSecond);
+
+ return (uint32_t)(minutes);
+}
+
+static gboolean
+check_calendar_type (guint16 type)
+{
+ /* Calendar Type - We support Gregorian only. */
+ if (type == CAL_DEFAULT || type == CAL_GREGORIAN)
+ return TRUE;
+ else {
+ g_warning ("Calendar type = 0x%04X - Evolution does not handle such calendar types.", type);
+ return FALSE;
}
}
@@ -76,29 +236,42 @@
guint16 flag16;
guint32 flag32;
guint8 *ptr = ba->data;
- GSList l;
gint i;
+ GSList *exdate_list = NULL, *modified_list = NULL;
+ gboolean repeats_until_date = FALSE;
icalrecurrencetype_clear (&rt);
- /* Major version */
- flag32 = *((guint32 *)ptr);
- ptr += sizeof (guint32);
- if (PREAMBLE != flag32)
+ /* Reader version */
+ flag16 = *((guint16 *)ptr);
+ ptr += sizeof (guint16);
+ if (READER_VERSION != flag16)
+ return FALSE;
+
+ /* Writer version */
+ flag16 = *((guint16 *)ptr);
+ ptr += sizeof (guint16);
+ if (WRITER_VERSION != flag16)
return FALSE;
/* FREQUENCY */
flag16 = *((guint16 *)ptr);
ptr += sizeof (guint16);
- if (flag16 == 0x200A) {
+ if (flag16 == RecurFrequency_Daily) {
rt.freq = ICAL_DAILY_RECURRENCE;
- flag32 = *((guint32 *)ptr);
- ptr += sizeof (guint32);
- if (flag32 == 0x0) {
+ flag16 = *((guint16 *)ptr);
+ ptr += sizeof (guint16);
+ if (flag16 == PatternType_Day) {
/* Daily every N days */
- /* some crappy mod here */
+ /* Calendar Type */
+ flag16 = *((guint16 *)ptr);
+ ptr += sizeof (guint16);
+ if (!check_calendar_type (flag16))
+ return FALSE;
+
+ /* FirstDateTime (some crappy mod here) */
flag32 = *((guint32 *)ptr);
ptr += sizeof (guint32);
@@ -112,15 +285,22 @@
ptr += sizeof (guint32);
if (flag32)
return FALSE;
- } else if (flag32 == 0x1) {
+
+ } else if (flag16 == PatternType_Week) {
/* Daily every weekday */
+ /* Calendar Type */
+ flag16 = *((guint16 *)ptr);
+ ptr += sizeof (guint16);
+ if (!check_calendar_type (flag16))
+ return FALSE;
+
/* NOTE: Evolution does not handle daily-every-weekday any different
* from a weekly recurrence.
*/
rt.freq = ICAL_WEEKLY_RECURRENCE;
- /* some crappy mod here */
+ /* FirstDateTime (some crappy mod here) */
flag32 = *((guint32 *)ptr);
ptr += sizeof (guint32);
@@ -156,15 +336,21 @@
rt.by_day[i++] = ICAL_SATURDAY_WEEKDAY;
}
- } else if (flag16 == 0x200B) {
+ } else if (flag16 == RecurFrequency_Weekly) {
rt.freq = ICAL_WEEKLY_RECURRENCE;
- flag32 = *((guint32 *)ptr);
- ptr += sizeof (guint32);
- if (flag32 == 0x1) {
+ flag16 = *((guint16 *)ptr);
+ ptr += sizeof (guint16);
+ if (flag16 == PatternType_Week) {
/* weekly every N weeks (for all events and non-regenerating tasks) */
- /* some crappy mod here */
+ /* Calendar Type */
+ flag16 = *((guint16 *)ptr);
+ ptr += sizeof (guint16);
+ if (!check_calendar_type (flag16))
+ return FALSE;
+
+ /* FirstDateTime (some crappy mod here) */
flag32 = *((guint32 *)ptr);
ptr += sizeof (guint32);
@@ -198,23 +384,37 @@
rt.by_day[i++] = ICAL_FRIDAY_WEEKDAY;
if (flag32 & olSaturday)
rt.by_day[i++] = ICAL_SATURDAY_WEEKDAY;
- } else if (flag32 == 0x0) {
+
+ } else if (flag16 == 0x0) {
/* weekly every N weeks (for all regenerating tasks) */
+ /* Calendar Type */
+ flag16 = *((guint16 *)ptr);
+ ptr += sizeof (guint16);
+ if (!check_calendar_type (flag16))
+ return FALSE;
+
/* FIXME: we don't handle regenerating tasks */
+ g_warning ("Evolution does not handle recurring tasks.");
return FALSE;
}
- } else if (flag16 == 0x200C) {
+ } else if (flag16 == RecurFrequency_Monthly) {
rt.freq = ICAL_MONTHLY_RECURRENCE;
- flag32 = *((guint32 *)ptr);
- ptr += sizeof (guint32);
-
- if (flag32 == 0x2) {
- /* Monthly every N months on day D */
+ flag16 = *((guint16 *)ptr);
+ ptr += sizeof (guint16);
+ if (flag16 == PatternType_Month || flag16 == PatternType_MonthEnd) {
+ guint16 pattern = flag16;
+ /* Monthly every N months on day D or last day. */
+
+ /* Calendar Type */
+ flag16 = *((guint16 *)ptr);
+ ptr += sizeof (guint16);
+ if (!check_calendar_type (flag16))
+ return FALSE;
- /* some crappy mod here */
+ /* FirstDateTime (some crappy mod here) */
flag32 = *((guint32 *)ptr);
ptr += sizeof (guint32);
@@ -229,14 +429,26 @@
if (flag32)
return FALSE;
- /* MONTH_DAY */
+ /* MONTH_DAY */
flag32 = *((guint32 *)ptr);
ptr += sizeof (guint32);
- rt.by_month_day[0] = (short) (flag32);
- } else if (flag32 == 0x3) {
+ if (pattern == PatternType_Month)
+ rt.by_month_day[0] = (short) (flag32);
+ else if (pattern == PatternType_MonthEnd)
+ rt.by_month_day[0] = (short) (-1);
+
+ } else if (flag16 == PatternType_MonthNth) {
+ gboolean post_process = FALSE;
+ guint32 mask = 0;
/* Monthly every N months on the Xth Y */
- /* some crappy mod here */
+ /* Calendar Type */
+ flag16 = *((guint16 *)ptr);
+ ptr += sizeof (guint16);
+ if (!check_calendar_type (flag16))
+ return FALSE;
+
+ /* FirstDateTime (some crappy mod here) */
flag32 = *((guint32 *)ptr);
ptr += sizeof (guint32);
@@ -250,23 +462,64 @@
ptr += sizeof (guint32);
if (flag32)
return FALSE;
-
+ /* BITMASK */
flag32 = *((guint32 *)ptr);
ptr += sizeof (guint32);
- if (flag32 > 4)
-
+ if (flag32 == olSunday)
+ rt.by_day[0] = ICAL_SUNDAY_WEEKDAY;
+ else if (flag32 == olMonday)
+ rt.by_day[0] = ICAL_MONDAY_WEEKDAY;
+ else if (flag32 == olTuesday)
+ rt.by_day[0] = ICAL_TUESDAY_WEEKDAY;
+ else if (flag32 == olWednesday)
+ rt.by_day[0] = ICAL_WEDNESDAY_WEEKDAY;
+ else if (flag32 == olThursday)
+ rt.by_day[0] = ICAL_THURSDAY_WEEKDAY;
+ else if (flag32 == olFriday)
+ rt.by_day[0] = ICAL_FRIDAY_WEEKDAY;
+ else if (flag32 == olSaturday)
+ rt.by_day[0] = ICAL_SATURDAY_WEEKDAY;
+ else {
+ post_process = TRUE;
+ mask = flag32;
+ }
+
+ /* RecurrenceN */
+ flag32 = *((guint32 *)ptr);
+ ptr += sizeof (guint32);
+ if (!post_process) {
+ rt.by_set_pos[0] = get_ical_pos (flag32);
+ if (rt.by_set_pos[0] == 0)
+ return FALSE;
+ } else {
+ if (mask == (olSunday | olMonday | olTuesday | olWednesday | olThursday | olFriday | olSaturday)) {
+ rt.by_month_day[0] = get_ical_pos (flag32);
+ if (rt.by_month_day[0] == 0)
+ return FALSE;
+ } else {
+ /* FIXME: Can we/LibICAL support any other types here? Namely, weekday and weekend-day */
+ g_warning ("Encountered a recurrence type Evolution cannot handle. ");
+ return FALSE;
+ }
+ }
}
- } else if (flag16 == 0x200D) {
+ } else if (flag16 == RecurFrequency_Yearly) {
rt.freq = ICAL_YEARLY_RECURRENCE;
- flag32 = *((guint32 *)ptr);
- ptr += sizeof (guint32);
-
- if (flag32 == 0x2) {
+ flag16 = *((guint16 *)ptr);
+ ptr += sizeof (guint16);
+ if (flag16 == PatternType_Month) {
/* Yearly on day D of month M */
+ /* Calendar Type */
+ flag16 = *((guint16 *)ptr);
+ ptr += sizeof (guint16);
+ if (!check_calendar_type (flag16))
+ return FALSE;
+
+ /* FirstDateTime (some crappy mod here) */
flag32 = *((guint32 *)ptr);
ptr += sizeof (guint32);
@@ -281,12 +534,22 @@
if (flag32)
return FALSE;
+ /* MONTH_DAY - but we don't need this */
flag32 = *((guint32 *)ptr);
ptr += sizeof (guint32);
- } else if (flag32 == 0x3) {
+
+ } else if (flag16 == PatternType_MonthNth) {
/* Yearly on the Xth Y of month M */
- g_warning ("Encountered a recurrence pattern Evolution cannot handle");
+ g_warning ("Encountered a recurrence pattern Evolution cannot handle.");
+
+ /* Calendar Type */
+ flag16 = *((guint16 *)ptr);
+ ptr += sizeof (guint16);
+ if (!check_calendar_type (flag16))
+ return FALSE;
+
+ /* FirstDateTime (some crappy mod here) */
flag32 = *((guint32 *)ptr);
ptr += sizeof (guint32);
@@ -301,9 +564,11 @@
if (flag32)
return FALSE;
+ /* BITMASK */
flag32 = *((guint32 *)ptr);
ptr += sizeof (guint32);
+ /* RecurrenceN */
flag32 = *((guint32 *)ptr);
ptr += sizeof (guint32);
@@ -313,108 +578,575 @@
} else
return FALSE;
- /* repeat */
+ /* End Type - followed by Occurence count */
flag32 = *((guint32 *)ptr);
ptr += sizeof (guint32);
- if (flag32 == REPEAT_UNTIL) {
+ if (flag32 == END_AFTER_DATE) {
flag32 = *((guint32 *)ptr);
ptr += sizeof (guint32);
- } else if (flag32 == REPEAT_FOR_N) {
+
+ repeats_until_date = TRUE;
+ } else if (flag32 == END_AFTER_N_OCCURRENCES) {
flag32 = *((guint32 *)ptr);
ptr += sizeof (guint32);
rt.count = flag32;
- } else if (flag32 == REPEAT_FOREVER) {
+ } else if (flag32 == END_NEVER_END) {
flag32 = *((guint32 *)ptr);
ptr += sizeof (guint32);
- if (flag32)
- return FALSE;
}
/* week_start */
flag32 = *((guint32 *)ptr);
ptr += sizeof (guint32);
- rt.week_start = get_ical_weekday (flag32);
-g_print ("week start %x\n", flag32);
+ rt.week_start = get_ical_weekstart (flag32);
/* number of exceptions */
flag32 = *((guint32 *)ptr);
ptr += sizeof (guint32);
- /* fixme: exceptions */
- if (flag32)
- ptr += flag32 * sizeof (guint32);
-g_print ("excpt no %x\n", flag32);
+ if (flag32) {
+ for (i = 0; i < flag32; ++i) {
+ uint32_t exdate;
+ struct icaltimetype tt, *val;
+ ECalComponentDateTime *dt = g_new0 (ECalComponentDateTime, 1);
+
+ exdate = *((guint32 *)ptr);
+ ptr += sizeof (guint32);
+
+ tt = icaltime_from_timet_with_zone (convert_recurrence_minutes_to_timet (exdate), 1, 0);
+
+ val = g_new0(struct icaltimetype, 1);
+ memcpy (val, &tt, sizeof(struct icaltimetype));
+
+ dt->value = val;
+ dt->tzid = g_strdup ("UTC");
+
+ exdate_list = g_slist_append (exdate_list, dt);
+ }
+ }
/* number of changed exceptions */
flag32 = *((guint32 *)ptr);
ptr += sizeof (guint32);
- /* fixme: exceptions */
+ /* FIXME: Parse modified instances */
if (flag32)
ptr += flag32 * sizeof (guint32);
-g_print ("changed excpt %x\n", flag32);
/* start date */
flag32 = *((guint32 *)ptr);
ptr += sizeof (guint32);
-g_print ("start date %x\n", flag32);
/* end date */
flag32 = *((guint32 *)ptr);
ptr += sizeof (guint32);
-g_print ("end date %x\n", flag32);
+ if (repeats_until_date) {
+ rt.until = icaltime_from_timet_with_zone (convert_recurrence_minutes_to_timet (flag32), 1, 0);
+ }
/* some constant */
flag32 = *((guint32 *)ptr);
ptr += sizeof (guint32);
- if (flag32 != VERSION_PREAMBLE)
+ if (flag32 != READER_VERSION2)
return FALSE;
-g_print ("constant %x\n", flag32);
- /* version info */
+ /* some constant */
flag32 = *((guint32 *)ptr);
ptr += sizeof (guint32);
- if (flag32 != VERSION_ID)
+ if (flag32 != WRITER_VERSION2)
return FALSE;
-g_print ("ver info %x\n", flag32);
/* start time in mins */
flag32 = *((guint32 *)ptr);
ptr += sizeof (guint32);
-g_print ("start time in mins %x\n", flag32);
/* end time in mins */
flag32 = *((guint32 *)ptr);
ptr += sizeof (guint32);
-g_print ("end time in mins %x\n", flag32);
- /* exceptions */
+ /* modified exceptions */
flag16 = *((guint16 *)ptr);
ptr += sizeof (guint16);
if (flag16 != 0x0)
return FALSE;
-g_print ("excpt no %x\n", flag16);
- /* term seq */
+ /* reserved block1 size - has to be 0 */
flag32 = *((guint32 *)ptr);
ptr += sizeof (guint32);
- if (flag32 != TERMINAL_SEQ)
+ if (flag32 != 0x0)
return FALSE;
-g_print ("term seq 1 %x\n", flag32);
- /* term seq */
+ /* reserved block2 size - has to be 0 */
flag32 = *((guint32 *)ptr);
ptr += sizeof (guint32);
- if (flag32 != TERMINAL_SEQ)
+ if (flag32 != 0x0)
return FALSE;
/* Set the recurrence */
+ {
+ GSList l;
- l.data = &rt;
- l.next = NULL;
+ l.data = &rt;
+ l.next = NULL;
- e_cal_component_set_rrule_list (comp, &l);
+ e_cal_component_set_rrule_list (comp, &l);
+ }
- g_print ("\n\nyipppeee... parsed the blob..\n\n");
+ /* FIXME: this also has modified instances */
+ e_cal_component_set_exdate_list (comp, exdate_list);
+
+ g_print ("\n== MAPI to ICAL == The recurrence blob data is as follows:\n");
+ for (i = 0; i < ba->len; ++i)
+ g_print ("0x%02X ", ba->data[i]);
+ g_print("\n== End of stream ==\n");
return TRUE;
}
+
+static guint32
+compute_startdate (ECalComponent *comp)
+{
+ ECalComponentDateTime dtstart;
+ guint32 flag32;
+
+ e_cal_component_get_dtstart (comp, &dtstart);
+ dtstart.value->hour = dtstart.value->minute = dtstart.value->second = 0;
+ flag32 = convert_timet_to_recurrence_minutes (icaltime_as_timet_with_zone (*(dtstart.value), 0));
+
+ e_cal_component_free_datetime (&dtstart);
+
+ return flag32;
+}
+
+static guint32
+compute_rdaily_firstdatetime (ECalComponent *comp, guint32 period)
+{
+ return (compute_startdate (comp) % period);
+}
+
+static guint32
+compute_rweekly_firstdatetime (ECalComponent *comp, icalrecurrencetype_weekday week_start, guint32 period)
+{
+ ECalComponentDateTime dtstart;
+ guint32 flag32;
+ int cur_weekday = 0, weekstart_weekday = 0, diff = 0;
+ time_t t;
+
+ e_cal_component_get_dtstart (comp, &dtstart);
+ dtstart.value->hour = dtstart.value->minute = dtstart.value->second = 0;
+ cur_weekday = icaltime_day_of_week (*(dtstart.value));
+ t = icaltime_as_timet_with_zone (*(dtstart.value), 0);
+ e_cal_component_free_datetime (&dtstart);
+
+ switch (week_start) {
+ case ICAL_SUNDAY_WEEKDAY : weekstart_weekday = 1; break;
+ case ICAL_MONDAY_WEEKDAY : weekstart_weekday = 2; break;
+ case ICAL_TUESDAY_WEEKDAY : weekstart_weekday = 3; break;
+ case ICAL_WEDNESDAY_WEEKDAY : weekstart_weekday = 4; break;
+ case ICAL_THURSDAY_WEEKDAY : weekstart_weekday = 5; break;
+ case ICAL_FRIDAY_WEEKDAY : weekstart_weekday = 6; break;
+ case ICAL_SATURDAY_WEEKDAY : weekstart_weekday = 7; break;
+ default : weekstart_weekday = 1; break;
+ };
+
+ diff = cur_weekday - weekstart_weekday;
+
+ if (diff == 0);
+ else if (diff > 0)
+ t -= (diff * 24 * 60 * 60);
+ else if (diff < 0)
+ t -= ((diff + 7) * 24 * 60 * 60);
+
+ flag32 = convert_timet_to_recurrence_minutes (t);
+
+ return (flag32 % period);
+}
+
+/* The most fucked up algorithm ever conceived by (..you know who..) */
+static guint32
+compute_rmonthly_firstdatetime (ECalComponent *comp, guint32 period)
+{
+ const guint8 dinm[] = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
+ ECalComponentDateTime dtstart;
+ guint32 flag32, monthindex, i;
+
+ e_cal_component_get_dtstart (comp, &dtstart);
+ monthindex = (guint32)((((guint64)(12) * (dtstart.value->year - 1601)) + (dtstart.value->month - 1)) % period);
+ e_cal_component_free_datetime (&dtstart);
+
+ for (flag32 = 0, i = 0; i < monthindex; ++i)
+ flag32 += dinm[(i % 12) + 1] * 24 * 60;
+
+ return flag32;
+}
+
+static guint32
+calculate_no_of_occurrences (ECalComponent *comp, const struct icalrecurrencetype *rt)
+{
+ ECalComponentDateTime dtstart;
+ icalrecur_iterator *iter;
+ struct icaltimetype next;
+ guint32 count = 1;
+
+ e_cal_component_get_dtstart (comp, &dtstart);
+
+ for (iter = icalrecur_iterator_new (*rt, *(dtstart.value)),
+ next = icalrecur_iterator_next(iter);
+ !icaltime_is_null_time(next);
+ next = icalrecur_iterator_next(iter))
+ ++count;
+
+ icalrecur_iterator_free (iter);
+ e_cal_component_free_datetime (&dtstart);
+
+ return count;
+}
+
+static gint
+compare_guint32 (gconstpointer a, gconstpointer b, gpointer user_data)
+{
+ return (*((guint32 *) a) - *((guint32 *) b));
+}
+
+GByteArray *
+exchange_mapi_cal_util_rrule_to_bin (ECalComponent *comp, GSList *modified_comps)
+{
+ struct icalrecurrencetype *rt;
+ guint16 flag16;
+ guint32 flag32, end_type;
+ gint i;
+ GSList *rrule_list = NULL, *exdate_list = NULL;
+ GByteArray *ba = NULL;
+
+ if (!e_cal_component_has_recurrences (comp))
+ return NULL;
+
+ e_cal_component_get_rrule_list (comp, &rrule_list);
+ e_cal_component_get_exdate_list (comp, &exdate_list);
+
+ if (g_slist_length (rrule_list) != 1)
+ goto cleanup;
+
+ rt = (struct icalrecurrencetype *)(rrule_list->data);
+
+ ba = g_byte_array_new ();
+
+ /* Reader Version */
+ flag16 = READER_VERSION;
+ ba = g_byte_array_append (ba, &flag16, sizeof (guint16));
+
+ /* Writer Version */
+ flag16 = WRITER_VERSION;
+ ba = g_byte_array_append (ba, &flag16, sizeof (guint16));
+
+ if (rt->freq == ICAL_DAILY_RECURRENCE) {
+ flag16 = RecurFrequency_Daily;
+ ba = g_byte_array_append (ba, &flag16, sizeof (guint16));
+
+ /* Pattern Type - it would be PatternType_Day since we have only "Daily every N days"
+ * The other type would be parsed as a weekly recurrence.
+ */
+ flag16 = PatternType_Day;
+ ba = g_byte_array_append (ba, &flag16, sizeof (guint16));
+
+ /* Calendar Type */
+ flag16 = CAL_DEFAULT;
+ ba = g_byte_array_append (ba, &flag16, sizeof (guint16));
+
+ /* FirstDateTime */
+ flag32 = compute_rdaily_firstdatetime (comp, (rt->interval * (60 * 24)));
+ ba = g_byte_array_append (ba, &flag32, sizeof (guint32));
+
+ /* INTERVAL */
+ flag32 = (rt->interval * (60 * 24));
+ ba = g_byte_array_append (ba, &flag32, sizeof (guint32));
+
+ /* This would be 0 for the stuff we handle */
+ flag32 = 0x0;
+ ba = g_byte_array_append (ba, &flag32, sizeof (guint32));
+
+ /* No PatternTypeSpecific for PatternType_Day */
+
+ } else if (rt->freq == ICAL_WEEKLY_RECURRENCE) {
+ flag16 = RecurFrequency_Weekly;
+ ba = g_byte_array_append (ba, &flag16, sizeof (guint16));
+
+ /* Pattern Type - it would be PatternType_Week since we don't support any other type. */
+ flag16 = PatternType_Week;
+ ba = g_byte_array_append (ba, &flag16, sizeof (guint16));
+
+ /* Calendar Type */
+ flag16 = CAL_DEFAULT;
+ ba = g_byte_array_append (ba, &flag16, sizeof (guint16));
+
+ /* FirstDateTime */
+ flag32 = compute_rweekly_firstdatetime (comp, rt->week_start, (rt->interval * (60 * 24 * 7)));
+ ba = g_byte_array_append (ba, &flag32, sizeof (guint32));
+
+ /* INTERVAL */
+ flag32 = rt->interval;
+ ba = g_byte_array_append (ba, &flag32, sizeof (guint32));
+
+ /* This would be 0 for the stuff we handle */
+ flag32 = 0x0;
+ ba = g_byte_array_append (ba, &flag32, sizeof (guint32));
+
+ /* BITMASK */
+ for (flag32 = 0x0, i = 0; i < ICAL_BY_DAY_SIZE; ++i) {
+ if (rt->by_day[i] == ICAL_SUNDAY_WEEKDAY)
+ flag32 |= olSunday;
+ else if (rt->by_day[i] == ICAL_MONDAY_WEEKDAY)
+ flag32 |= olMonday;
+ else if (rt->by_day[i] == ICAL_TUESDAY_WEEKDAY)
+ flag32 |= olTuesday;
+ else if (rt->by_day[i] == ICAL_WEDNESDAY_WEEKDAY)
+ flag32 |= olWednesday;
+ else if (rt->by_day[i] == ICAL_THURSDAY_WEEKDAY)
+ flag32 |= olThursday;
+ else if (rt->by_day[i] == ICAL_FRIDAY_WEEKDAY)
+ flag32 |= olFriday;
+ else if (rt->by_day[i] == ICAL_SATURDAY_WEEKDAY)
+ flag32 |= olSaturday;
+ else
+ break;
+ }
+ ba = g_byte_array_append (ba, &flag32, sizeof (guint32));
+
+ } else if (rt->freq == ICAL_MONTHLY_RECURRENCE) {
+ guint16 pattern = 0x0; guint32 mask = 0x0, flag = 0x0;
+
+ flag16 = RecurFrequency_Monthly;
+ ba = g_byte_array_append (ba, &flag16, sizeof (guint16));
+
+ if (rt->by_month_day[0] >= 1 && rt->by_month_day[0] <= 31) {
+ pattern = PatternType_Month;
+ flag = rt->by_month_day[0];
+ } else if (rt->by_month_day[0] == -1) {
+ pattern = PatternType_MonthNth;
+ mask = (olSunday | olMonday | olTuesday | olWednesday | olThursday | olFriday | olSaturday);
+ flag = RecurrenceN_Last;
+ } else if (rt->by_day[0] >= ICAL_SUNDAY_WEEKDAY && rt->by_day[0] <= ICAL_SATURDAY_WEEKDAY) {
+ pattern = PatternType_MonthNth;
+ mask = get_mapi_day (rt->by_day[0]);
+ flag = get_mapi_pos (rt->by_set_pos[0]);
+ }
+
+ /* Pattern Type */
+ flag16 = pattern;
+ ba = g_byte_array_append (ba, &flag16, sizeof (guint16));
+
+ /* Calendar Type */
+ flag16 = CAL_DEFAULT;
+ ba = g_byte_array_append (ba, &flag16, sizeof (guint16));
+
+ /* FirstDateTime */
+ flag32 = compute_rmonthly_firstdatetime (comp, rt->interval);
+ ba = g_byte_array_append (ba, &flag32, sizeof (guint32));
+
+ /* INTERVAL */
+ flag32 = rt->interval;
+ ba = g_byte_array_append (ba, &flag32, sizeof (guint32));
+
+ /* This would be 0 for the stuff we handle */
+ flag32 = 0x0;
+ ba = g_byte_array_append (ba, &flag32, sizeof (guint32));
+
+ if (pattern == PatternType_Month) {
+ flag32 = flag;
+ ba = g_byte_array_append (ba, &flag32, sizeof (guint32));
+
+ if (!(flag))
+ g_warning ("Possibly setting incorrect values in the stream. ");
+ } else if (pattern == PatternType_MonthNth) {
+ flag32 = mask;
+ ba = g_byte_array_append (ba, &flag32, sizeof (guint32));
+
+ flag32 = flag;
+ ba = g_byte_array_append (ba, &flag32, sizeof (guint32));
+
+ if (!(flag && mask))
+ g_warning ("Possibly setting incorrect values in the stream. ");
+ } else
+ g_warning ("Possibly setting incorrect values in the stream. ");
+
+ } else if (rt->freq == ICAL_YEARLY_RECURRENCE) {
+ flag16 = RecurFrequency_Yearly;
+ ba = g_byte_array_append (ba, &flag16, sizeof (guint16));
+
+ /* Pattern Type - it would be PatternType_Month since we don't support any other type. */
+ flag16 = PatternType_Month;
+ ba = g_byte_array_append (ba, &flag16, sizeof (guint16));
+
+ /* Calendar Type */
+ flag16 = CAL_DEFAULT;
+ ba = g_byte_array_append (ba, &flag16, sizeof (guint16));
+
+ /* FirstDateTime - uses the same function as monthly recurrence */
+ flag32 = compute_rmonthly_firstdatetime (comp, 0xC);
+ ba = g_byte_array_append (ba, &flag32, sizeof (guint32));
+
+ /* INTERVAL - should be 12 for yearly recurrence */
+ flag32 = 0xC;
+ ba = g_byte_array_append (ba, &flag32, sizeof (guint32));
+
+ /* This would be 0 for the stuff we handle */
+ flag32 = 0x0;
+ ba = g_byte_array_append (ba, &flag32, sizeof (guint32));
+
+ /* MONTH_DAY */
+ {
+ ECalComponentDateTime dtstart;
+ e_cal_component_get_dtstart (comp, &dtstart);
+ flag32 = dtstart.value->day;
+ e_cal_component_free_datetime (&dtstart);
+ }
+ ba = g_byte_array_append (ba, &flag32, sizeof (guint32));
+
+ }
+
+ /* End Type followed by Occurence count */
+ if (!icaltime_is_null_time (rt->until)) {
+ flag32 = END_AFTER_DATE;
+ ba = g_byte_array_append (ba, &flag32, sizeof (guint32));
+
+ flag32 = calculate_no_of_occurrences (comp, rt);
+ ba = g_byte_array_append (ba, &flag32, sizeof (guint32));
+
+ end_type = END_AFTER_DATE;
+ } else if (rt->count) {
+ flag32 = END_AFTER_N_OCCURRENCES;
+ ba = g_byte_array_append (ba, &flag32, sizeof (guint32));
+
+ flag32 = rt->count;
+ ba = g_byte_array_append (ba, &flag32, sizeof (guint32));
+
+ end_type = END_AFTER_N_OCCURRENCES;
+ } else {
+ flag32 = END_NEVER_END;
+ ba = g_byte_array_append (ba, &flag32, sizeof (guint32));
+
+ flag32 = 0x0;
+ ba = g_byte_array_append (ba, &flag32, sizeof (guint32));
+
+ end_type = END_NEVER_END;
+ }
+
+ /* FirstDOW */
+ flag32 = get_mapi_weekstart (rt->week_start);
+ ba = g_byte_array_append (ba, &flag32, sizeof (guint32));
+
+ /* DeletedInstances */
+ flag32 = g_slist_length (exdate_list);
+ ba = g_byte_array_append (ba, &flag32, sizeof (guint32));
+ if (flag32) {
+ GSList *l;
+ guint32 *sorted_list = g_new0(guint32, flag32);
+ /* FIXME: This should include modified dates */
+ for (i = 0, l = exdate_list; l; ++i, l = l->next) {
+ ECalComponentDateTime *dt = (ECalComponentDateTime *)(l->data);
+ dt->value->hour = dt->value->minute = dt->value->second = 0;
+ sorted_list[i] = convert_timet_to_recurrence_minutes (icaltime_as_timet_with_zone (*(dt->value), 0));
+ }
+
+ g_qsort_with_data (sorted_list, flag32, sizeof (guint32), compare_guint32, NULL);
+
+ for (i = 0; i < flag32; ++i)
+ ba = g_byte_array_append (ba, &(sorted_list[i]), sizeof (guint32));
+
+ g_free (sorted_list);
+ }
+
+ /* FIXME: Add support for modified instances */
+ /* ModifiedInstanceCount */
+ flag32 = 0x0;
+ ba = g_byte_array_append (ba, &flag32, sizeof (guint32));
+ if (flag32) {
+ }
+
+ /* StartDate */
+ flag32 = compute_startdate (comp);
+ ba = g_byte_array_append (ba, &flag32, sizeof (guint32));
+
+ /* EndDate */
+ {
+ if (end_type == END_NEVER_END)
+ flag32 = 0x5AE980DF;
+ else if (end_type == END_AFTER_N_OCCURRENCES) {
+ ECalComponentDateTime dtstart;
+ gchar *rrule_str = icalrecurrencetype_as_string (rt);
+ time_t *array = g_new0 (time_t, rt->count);
+
+ e_cal_component_get_dtstart (comp, &dtstart);
+ dtstart.value->hour = dtstart.value->minute = dtstart.value->second = 0;
+
+ icalrecur_expand_recurrence (rrule_str, icaltime_as_timet_with_zone (*(dtstart.value), 0), rt->count, array);
+
+ flag32 = convert_timet_to_recurrence_minutes (array[(rt->count) - 1]);
+
+ g_free (array);
+ g_free (rrule_str);
+ e_cal_component_free_datetime (&dtstart);
+ } else if (end_type == END_AFTER_DATE) {
+ struct icaltimetype until;
+ memcpy (&until, &(rt->until), sizeof(struct icaltimetype));
+ until.hour = until.minute = until.second = 0;
+ flag32 = convert_timet_to_recurrence_minutes (icaltime_as_timet_with_zone (until, 0));
+ } else
+ flag32 = 0x0;
+ }
+ ba = g_byte_array_append (ba, &flag32, sizeof (guint32));
+
+ /* Reader Version 2 */
+ flag32 = READER_VERSION2;
+ ba = g_byte_array_append (ba, &flag32, sizeof (guint32));
+
+ /* Writer Version 2 */
+ flag32 = WRITER_VERSION2;
+ ba = g_byte_array_append (ba, &flag32, sizeof (guint32));
+
+ /* StartTimeOffset */
+ {
+ ECalComponentDateTime dtstart;
+ e_cal_component_get_dtstart (comp, &dtstart);
+ flag32 = (dtstart.value->hour * 60) + dtstart.value->minute;
+ e_cal_component_free_datetime (&dtstart);
+ }
+ ba = g_byte_array_append (ba, &flag32, sizeof (guint32));
+
+ /* EndTimeOffset */
+ {
+ ECalComponentDateTime dtend;
+ e_cal_component_get_dtend (comp, &dtend);
+ flag32 = (dtend.value->hour * 60) + dtend.value->minute;
+ e_cal_component_free_datetime (&dtend);
+ }
+ ba = g_byte_array_append (ba, &flag32, sizeof (guint32));
+
+ /* FIXME: Add support for modified instances */
+ /* ModifiedExceptionCount */
+ flag16 = 0x0;
+ ba = g_byte_array_append (ba, &flag16, sizeof (guint16));
+
+ /* FIXME: Add the ExceptionInfo here */
+
+ /* Reserved Block 1 Size */
+ flag32 = 0x0;
+ ba = g_byte_array_append (ba, &flag32, sizeof (guint32));
+
+ /* FIXME: Add the ExtendedExceptionInfo here */
+
+ /* Reserved Block 2 Size */
+ flag32 = 0x0;
+ ba = g_byte_array_append (ba, &flag32, sizeof (guint32));
+
+cleanup:
+ e_cal_component_free_exdate_list (exdate_list);
+ e_cal_component_free_recur_list (rrule_list);
+
+ g_print ("\n== ICAL to MAPI == The recurrence blob data is as follows:\n");
+ for (i = 0; i < ba->len; ++i)
+ g_print ("0x%02X ", ba->data[i]);
+ g_print("\n== End of stream ==\n");
+
+ return ba;
+}
+
Modified: branches/EXCHANGE_MAPI_BRANCH/servers/mapi/exchange-mapi-cal-recur-utils.h
==============================================================================
--- branches/EXCHANGE_MAPI_BRANCH/servers/mapi/exchange-mapi-cal-recur-utils.h (original)
+++ branches/EXCHANGE_MAPI_BRANCH/servers/mapi/exchange-mapi-cal-recur-utils.h Fri Sep 5 05:54:08 2008
@@ -28,11 +28,16 @@
#include <glib.h>
+#include "exchange-mapi-cal-utils.h"
+
G_BEGIN_DECLS
gboolean
exchange_mapi_cal_util_bin_to_rrule (GByteArray *ba, ECalComponent *comp);
+GByteArray *
+exchange_mapi_cal_util_rrule_to_bin (ECalComponent *comp, GSList *modified_comps);
+
G_END_DECLS
#endif
Modified: branches/EXCHANGE_MAPI_BRANCH/servers/mapi/exchange-mapi-cal-tz-utils.h
==============================================================================
--- branches/EXCHANGE_MAPI_BRANCH/servers/mapi/exchange-mapi-cal-tz-utils.h (original)
+++ branches/EXCHANGE_MAPI_BRANCH/servers/mapi/exchange-mapi-cal-tz-utils.h Fri Sep 5 05:54:08 2008
@@ -27,6 +27,7 @@
#define EXCHANGE_MAPI_CAL_TZ_UTILS_H
#include <glib.h>
+
#include "exchange-mapi-cal-utils.h"
G_BEGIN_DECLS
Modified: branches/EXCHANGE_MAPI_BRANCH/servers/mapi/exchange-mapi-cal-utils.c
==============================================================================
--- branches/EXCHANGE_MAPI_BRANCH/servers/mapi/exchange-mapi-cal-utils.c (original)
+++ branches/EXCHANGE_MAPI_BRANCH/servers/mapi/exchange-mapi-cal-utils.c Fri Sep 5 05:54:08 2008
@@ -701,8 +701,6 @@
subject = "";
body = (const gchar *)exchange_mapi_util_find_array_propval(properties, PR_BODY);
- if (!body)
- body = (const gchar *)exchange_mapi_util_find_array_propval(properties, PR_BODY_HTML);
if (!body) {
body_stream = exchange_mapi_util_find_stream (streams, PR_HTML);
body = body_stream ? (const gchar *) body_stream->value->data : "";
@@ -800,16 +798,6 @@
icalcomponent_add_property (ical_comp, prop);
}
- b = (const bool *)find_mapi_SPropValue_data(properties, PROP_TAG(PT_BOOLEAN, 0x8223));
- if (b && *b) {
- /* FIXME: recurrence */
- g_warning ("Encountered a recurring event.");
-/* stream = exchange_mapi_util_find_stream (streams, PROP_TAG(PT_BINARY, 0x8216));
- if (stream) {
- e_cal_backend_mapi_util_bin_to_rrule (stream->value, comp);
- }
-*/ }
-
if (recipients) {
b = (const bool *)find_mapi_SPropValue_data(properties, PR_RESPONSE_REQUESTED);
ical_attendees_from_props (ical_comp, recipients, (b && *b));
@@ -845,6 +833,14 @@
}
}
+ b = (const bool *)find_mapi_SPropValue_data(properties, PROP_TAG(PT_BOOLEAN, 0x8223));
+ if (b && *b) {
+ stream = exchange_mapi_util_find_stream (streams, PROP_TAG(PT_BINARY, 0x8216));
+ if (stream) {
+ exchange_mapi_cal_util_bin_to_rrule (stream->value, comp);
+ }
+ }
+
b = (const bool *)find_mapi_SPropValue_data(properties, PROP_TAG(PT_BOOLEAN, 0x8503));
if (b && *b) {
struct timeval start, displaytime;
@@ -1098,7 +1094,7 @@
#if 0
gchar *filename = g_build_filename (g_get_home_dir (), TEMP_ATTACH_STORE, NULL);
gchar *fileuri = g_filename_to_uri (filename, NULL, NULL);
- GSList *attachments = NULL, *recipients = NULL;
+ GSList *attachments = NULL, *recipients = NULL, *streams = NULL;
if (e_cal_component_has_attachments (cbdata.comp))
exchange_mapi_cal_util_fetch_attachments (cbdata.comp, &attachments, fileuri);
@@ -1116,7 +1112,7 @@
status = exchange_mapi_modify_item (olFolderCalendar, fid, mid,
exchange_mapi_cal_util_build_name_id, GINT_TO_POINTER (kind),
exchange_mapi_cal_util_build_props, &cbdata,
- recipients, attachments, MAPI_OPTIONS_DONT_SUBMIT);
+ recipients, attachments, streams, MAPI_OPTIONS_DONT_SUBMIT);
g_free (cbdata.props);
exchange_mapi_util_free_recipient_list (&recipients);
@@ -1387,7 +1383,7 @@
*/
-#define APPT_NAMED_PROPS_N 30
+#define APPT_NAMED_PROPS_N 29
#define DEFAULT_APPT_REMINDER_MINS 15
typedef enum
@@ -1396,37 +1392,37 @@
I_APPT_BUSYSTATUS ,
I_APPT_LOCATION ,
I_APPT_START ,
-/*5*/ I_APPT_END ,
+ I_APPT_END ,
I_APPT_DURATION ,
I_APPT_ALLDAY ,
-/**/ I_APPT_RECURBLOB ,
+ I_APPT_RECURBLOB ,
I_APPT_STATEFLAGS ,
-/*10*/ I_APPT_RESPONSESTATUS ,
+ I_APPT_RESPONSESTATUS ,
I_APPT_RECURRING ,
I_APPT_INTENDEDBUSY ,
-/**/ I_APPT_RECURBASE ,
+ I_APPT_RECURBASE ,
I_APPT_INVITED ,
-/*15*/ I_APPT_RECURTYPE ,
-/**/ I_APPT_RECURPATTERN ,
+ I_APPT_RECURTYPE ,
I_APPT_CLIPSTART ,
I_APPT_CLIPEND ,
I_APPT_AUTOLOCATION ,
-/*20*/ I_APPT_ISCOUNTERPROPOSAL ,
+ I_APPT_ISCOUNTERPROPOSAL ,
I_APPT_NOTALLOWPROPOSE ,
I_APPT_STARTTZBLOB ,
I_APPT_ENDTZBLOB ,
I_MEET_WHERE ,
-/*25*/ I_MEET_GUID ,
+ I_MEET_GUID ,
I_MEET_ISRECURRING ,
I_MEET_ISEXCEPTION ,
I_MEET_CLEANGUID ,
I_MEET_APPTMSGCLASS ,
-/*30*/ I_MEET_TYPE
+ I_MEET_TYPE
// I_APPT_SENDASICAL ,
// I_APPT_SEQTIME ,
// I_APPT_LABEL ,
+// I_APPT_RECURPATTERN ,
// I_APPT_DISPTZ ,
// I_APPT_ALLATTENDEES ,
// I_APPT_TOATTENDEES ,
@@ -1451,7 +1447,6 @@
mapi_nameid_lid_add(nameid, 0x8228, PSETID_Appointment); // PT_SYSTIME - RecurrenceBase
mapi_nameid_lid_add(nameid, 0x8229, PSETID_Appointment); // PT_BOOLEAN - FInvited
mapi_nameid_lid_add(nameid, 0x8231, PSETID_Appointment); // PT_LONG - RecurrenceType
- mapi_nameid_lid_add(nameid, 0x8232, PSETID_Appointment); // PT_STRING8 - RecurrencePattern
mapi_nameid_lid_add(nameid, 0x8235, PSETID_Appointment); // PT_SYSTIME - (dtstart)(for recurring events UTC 12 AM of day of start)
mapi_nameid_lid_add(nameid, 0x8236, PSETID_Appointment); // PT_SYSTIME - (dtend)(for recurring events UTC 12 AM of day of end)
mapi_nameid_lid_add(nameid, 0x823A, PSETID_Appointment); // PT_BOOLEAN - AutoFillLocation
@@ -1472,6 +1467,7 @@
// mapi_nameid_lid_add(nameid, 0x8200, PSETID_Appointment); // PT_BOOLEAN - SendAsICAL
// mapi_nameid_lid_add(nameid, 0x8202, PSETID_Appointment); // PT_SYSTIME - ApptSequenceTime
// mapi_nameid_lid_add(nameid, 0x8214, PSETID_Appointment); // PT_LONG - Label
+// mapi_nameid_lid_add(nameid, 0x8232, PSETID_Appointment); // PT_STRING8 - RecurrencePattern
// mapi_nameid_lid_add(nameid, 0x8234, PSETID_Appointment); // PT_STRING8 - display TimeZone
// mapi_nameid_lid_add(nameid, 0x8238, PSETID_Appointment); // PT_STRING8 - AllAttendees
// mapi_nameid_lid_add(nameid, 0x823B, PSETID_Appointment); // PT_STRING8 - ToAttendeesString (dupe PR_DISPLAY_TO)
@@ -1802,8 +1798,27 @@
b = (icaltime_is_date (dtstart) && icaltime_is_date (dtend));
set_SPropValue_proptag(&props[i++], proptag_array->aulPropTag[I_APPT_ALLDAY], (const void *) &b);
- /* FIXME: for RecurrenceType */
- flag32 = rectypeNone ;
+ if (e_cal_component_has_recurrences (comp)) {
+ GSList *rrule_list = NULL;
+ struct icalrecurrencetype *rt = NULL;
+
+ e_cal_component_get_rrule_list (comp, &rrule_list);
+ rt = (struct icalrecurrencetype *)(rrule_list->data);
+
+ if (rt->freq == ICAL_DAILY_RECURRENCE)
+ flag32 = rectypeDaily;
+ else if (rt->freq == ICAL_WEEKLY_RECURRENCE)
+ flag32 = rectypeWeekly;
+ else if (rt->freq == ICAL_MONTHLY_RECURRENCE)
+ flag32 = rectypeMonthly;
+ else if (rt->freq == ICAL_YEARLY_RECURRENCE)
+ flag32 = rectypeYearly;
+ else
+ flag32 = rectypeNone;
+
+ e_cal_component_free_recur_list (rrule_list);
+ } else
+ flag32 = rectypeNone;
set_SPropValue_proptag(&props[i++], proptag_array->aulPropTag[I_APPT_RECURTYPE], (const void *) &flag32);
flag32 = cbdata->appt_id;
@@ -1959,10 +1974,10 @@
break;
}
- /* FIXME: Recurring */
- b = e_cal_component_has_recurrences (comp) && FALSE; b = 0;
+ b = e_cal_component_has_recurrences (comp);
set_SPropValue_proptag(&props[i++], proptag_array->aulPropTag[I_APPT_RECURRING], (const void *) &b);
set_SPropValue_proptag(&props[i++], proptag_array->aulPropTag[I_MEET_ISRECURRING], (const void *) &b);
+ /* FIXME: Modified exceptions */
b = e_cal_component_has_exceptions (comp) && FALSE; b = 0;
set_SPropValue_proptag(&props[i++], proptag_array->aulPropTag[I_MEET_ISEXCEPTION], (const void *) &b);
Modified: branches/EXCHANGE_MAPI_BRANCH/servers/mapi/exchange-mapi-cal-utils.h
==============================================================================
--- branches/EXCHANGE_MAPI_BRANCH/servers/mapi/exchange-mapi-cal-utils.h (original)
+++ branches/EXCHANGE_MAPI_BRANCH/servers/mapi/exchange-mapi-cal-utils.h Fri Sep 5 05:54:08 2008
@@ -32,9 +32,7 @@
#include "exchange-mapi-utils.h"
#include "exchange-mapi-cal-tz-utils.h"
-#if 0
#include "exchange-mapi-cal-recur-utils.h"
-#endif
G_BEGIN_DECLS
@@ -112,8 +110,6 @@
PR_CONVERSATION_TOPIC_UNICODE,
PR_BODY,
PR_BODY_UNICODE,
- PR_BODY_HTML,
- PR_BODY_HTML_UNICODE,
PR_CREATION_TIME,
PR_LAST_MODIFICATION_TIME,
Modified: branches/EXCHANGE_MAPI_BRANCH/servers/mapi/exchange-mapi-connection.c
==============================================================================
--- branches/EXCHANGE_MAPI_BRANCH/servers/mapi/exchange-mapi-connection.c (original)
+++ branches/EXCHANGE_MAPI_BRANCH/servers/mapi/exchange-mapi-connection.c Fri Sep 5 05:54:08 2008
@@ -571,10 +571,10 @@
/* If there are any streams to be set, write them. */
exchange_mapi_util_write_generic_streams (&obj_attach, attachment->streams);
- /* message->SaveChanges() */
+ /* message->SaveChangesAttachment() */
retval = SaveChangesAttachment(obj_message, &obj_attach, KEEP_OPEN_READWRITE);
if (retval != MAPI_E_SUCCESS) {
- mapi_errstr("SaveChanges", GetLastError());
+ mapi_errstr("SaveChangesAttachment", GetLastError());
goto cleanup;
}
@@ -2022,7 +2022,7 @@
exchange_mapi_modify_item (uint32_t olFolder, mapi_id_t fid, mapi_id_t mid,
BuildNameID build_name_id, gpointer ni_data,
BuildProps build_props, gpointer p_data,
- GSList *recipients, GSList *attachments,
+ GSList *recipients, GSList *attachments, GSList *generic_streams,
uint32_t options)
{
enum MAPISTATUS retval;
@@ -2110,6 +2110,10 @@
goto cleanup;
}
+ if (generic_streams) {
+ exchange_mapi_util_write_generic_streams (&obj_message, generic_streams);
+ }
+
/* Set attachments if any */
if (attachments) {
exchange_mapi_util_set_attachments (&obj_message, attachments, TRUE);
Modified: branches/EXCHANGE_MAPI_BRANCH/servers/mapi/exchange-mapi-connection.h
==============================================================================
--- branches/EXCHANGE_MAPI_BRANCH/servers/mapi/exchange-mapi-connection.h (original)
+++ branches/EXCHANGE_MAPI_BRANCH/servers/mapi/exchange-mapi-connection.h Fri Sep 5 05:54:08 2008
@@ -148,7 +148,7 @@
exchange_mapi_modify_item (uint32_t olFolder, mapi_id_t fid, mapi_id_t mid,
BuildNameID build_name_id, gpointer ni_data,
BuildProps build_props, gpointer p_data,
- GSList *recipients, GSList *attachments,
+ GSList *recipients, GSList *attachments, GSList *generic_streams,
uint32_t options);
gboolean
Modified: branches/EXCHANGE_MAPI_BRANCH/servers/mapi/exchange-mapi-defs.h
==============================================================================
--- branches/EXCHANGE_MAPI_BRANCH/servers/mapi/exchange-mapi-defs.h (original)
+++ branches/EXCHANGE_MAPI_BRANCH/servers/mapi/exchange-mapi-defs.h Fri Sep 5 05:54:08 2008
@@ -237,6 +237,7 @@
olApptException = 3
} OlRecurrenceState;
+#if 0
typedef enum {
olRecursDaily = 0,
olRecursWeekly = 1,
@@ -245,6 +246,7 @@
olRecursYearly = 5,
olRecursYearNth = 6
} OlRecurrencePatternType;
+#endif
#define IPM_CONTACT "IPM.Contact"
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]