Hello, I am currently working on finishing the exchange2ical for GSOC and have run into a problem for the exdate specification.
According to MS-OXICAL section 2.2.1.20.13, the exdate property should be parsed from the DeletedInstanceDates array of the RecurrencePattern Struct. The RecurrencePattern struct is defined in MS-OXOCAL section 2.2.1.44.1 and is implemented in property.idl. The problem is that the DeletedInstanceDates array has random values that do not define the minutes from January 1st 1601 to the exception date as expected. Each time I run exchange2ical tool I retrieve a new set of random values. All other fields of the RecurrencePattern Struct are correct. Printing out the values of DeletedInstanceDates for 3 runs gives the following output: First Run: 35665600 0 35576768 0 Second Run: 32917184 0 32828352 0 Third Run: 29083328 0 28994496 0 The following is the relevant code: Retrieving the RecurrencePattern struct in exchange2ical.c: apptrecur = (struct Binary_r *) octool_get_propval(aRow, PidLidAppointmentRecur); exchange2ical->RecurrencePattern = get_RecurrencePattern(mem_ctx, apptrecur); how deletedinstancedates is parsed in exchange2ical_property.c: struct icaltimetype get_icaltime_from_Minutes(uint32_t mins){ struct timeval t; struct tm *tm; NTTIME nt; nt = mins; nt *= 10000000; nt *= 60; nttime_to_timeval(&t, nt); tm = gmtime(&t.tv_sec); return get_icaltimetype_from_tm(tm); } void ical_property_EXDATE(struct exchange2ical *exchange2ical) { uint32_t i; struct icaltimetype icaltime; icalproperty *prop; struct RecurrencePattern *pat = exchange2ical->RecurrencePattern; /* Sanity check */ if (exchange2ical->Recurring && (*exchange2ical->Recurring == 0x0)) return; if (!pat) return; if (!pat->DeletedInstanceCount) return; for (i = 0; i < pat->DeletedInstanceCount; i++) { /* If this is an all-day appointment */ if (exchange2ical->apptSubType && (*exchange2ical->apptSubType == 0x1)) { /* There is a bug in MS-OXOCAL * documentation. For all-day appointment, * DeletedInstanceDates is set to a value * which can't be the number of minutes since * blabla */ } else { /* number of minutes between midnight of the specified * day and midnight, January 1, 1601 */ icaltime= get_icaltime_from_Minutes(pat->DeletedInstanceDates[i]); prop = icalproperty_new_exdate(icaltime); icalcomponent_add_property(exchange2ical->vevent, prop); if (exchange2ical->TimeZoneDesc) { icalparameter *tzid = icalparameter_new_tzid(exchange2ical->TimeZoneDesc); icalproperty_add_parameter(prop, tzid); } } } } get_RecurrencePattern in libmapi/property.c : _PUBLIC_ struct RecurrencePattern *get_RecurrencePattern(TALLOC_CTX *mem_ctx, struct Binary_r *bin) { struct RecurrencePattern *RecurrencePattern = NULL; struct ndr_pull *ndr; enum ndr_err_code ndr_err_code; /* Sanity checks */ if (!bin) return NULL; if (!bin->cb) return NULL; if (!bin->lpb) return NULL; ndr = talloc_zero(mem_ctx, struct ndr_pull); ndr->offset = 0; ndr->data = bin->lpb; ndr->data_size = bin->cb; ndr_set_flags(&ndr->flags, LIBNDR_FLAG_NOALIGN); ndr->iconv_convenience = smb_iconv_convenience_init(mem_ctx, "CP850", "UTF8", true); RecurrencePattern = talloc_zero(mem_ctx, struct RecurrencePattern); ndr_err_code = ndr_pull_RecurrencePattern(ndr, NDR_SCALARS, RecurrencePattern); talloc_free(ndr); if (ndr_err_code != NDR_ERR_SUCCESS) { talloc_free(RecurrencePattern); return NULL; } return RecurrencePattern; } relevant property.idl: typedef [enum16bit] enum { RecurFrequency_Daily = 0x200A, RecurFrequency_Weekly = 0x200B, RecurFrequency_Monthly = 0x200C, RecurFrequency_Yearly = 0x200D } RecurFrequency; typedef [enum16bit] enum { PatternType_Day = 0x0, PatternType_Week = 0x1, PatternType_Month = 0x2, PatternType_MonthNth = 0x3, PatternType_MonthEnd = 0x4, PatternType_HjMonth = 0xA, PatternType_HjMonthNth = 0xB, PatternType_HjMonthEnd = 0xC } PatternType; typedef [enum16bit] enum { CAL_DEFAULT = 0x0, CAL_GREGORIAN = 0x1, CAL_GREGORIAN_US = 0x2, CAL_JAPAN = 0x3, CAL_TAIWAN = 0x4, CAL_KOREA = 0x5, CAL_HIJRI = 0x6, CAL_THAI = 0x7, CAL_HEBREW = 0x8, CAL_GREGORIAN_ME_FRENCH = 0x9, CAL_GREGORIAN_ARABIC = 0xA, CAL_GREGORIAN_XLIT_ENGLISH = 0xB, CAL_GREGORIAN_XLIT_FRENCH = 0xC, CAL_LUNAR_JAPANESE = 0xE, CAL_CHINESE_LUNAR = 0xF, CAL_SAKA = 0x10, CAL_LUNAR_KOREAN = 0x14 } CalendarType; typedef [bitmap32bit] bitmap { Su = 0x00000001, M = 0x00000002, Tu = 0x00000004, W = 0x00000008, Th = 0x00000010, F = 0x00000020, Sa = 0x00000040 } WeekRecurrencePattern; typedef [v1_enum] enum { RecurrenceN_First = 0x1, RecurrenceN_Second = 0x2, RecurrenceN_Third = 0x3, RecurrenceN_Fourth = 0x4, RecurrenceN_Last = 0x5 } RecurrenceN; typedef [flag(NDR_NOALIGN)] struct { WeekRecurrencePattern WeekRecurrencePattern; RecurrenceN N; } MonthRecurrencePattern; typedef [nodiscriminant,flag(NDR_NOALIGN)] union { [case(0x1)] WeekRecurrencePattern WeekRecurrencePattern; [case(0x2)] uint32 Day; [case(0x3)] MonthRecurrencePattern MonthRecurrencePattern; [case(0x4)] uint32 Day; [case(0xA)] uint32 Day; [case(0xB)] MonthRecurrencePattern MonthRecurrencePattern; [case(0xC)] uint32 Day; [case(0x0)]; [default]; } PatternTypeSpecific; typedef [v1_enum] enum { END_AFTER_DATE = 0x00002021, END_AFTER_N_OCCURRENCES = 0x00002022, END_NEVER_END = 0x00002023, NEVER_END = 0xFFFFFFFF } EndType; typedef [v1_enum] enum { FirstDOW_Sunday = 0x0, FirstDOW_Monday = 0x1, FirstDOW_Tuesday = 0x2, FirstDOW_Wednesday = 0x3, FirstDOW_Thursday = 0x4, FirstDOW_Friday = 0x5, FirstDOW_Saturday = 0x6 } FirstDOW; typedef [public,flag(NDR_NOALIGN)] struct { uint16 ReaderVersion; uint16 WriterVersion; RecurFrequency RecurFrequency; PatternType PatternType; CalendarType CalendarType; uint32 FirstDateTime; uint32 Period; uint32 SlidingFlag; [switch_is(PatternType)] PatternTypeSpecific PatternTypeSpecific; EndType EndType; uint32 OccurrenceCount; FirstDOW FirstDOW; uint32 DeletedInstanceCount; uint32 DeletedInstanceDates[DeletedInstanceCount]; uint32 ModifiedInstanceCount; uint32 ModifiedInstanceDates[ModifiedInstanceCount]; uint32 StartDate; uint32 EndDate; } RecurrencePattern; Any help will be appreciated. Thanks, Ryan Lepinski
_______________________________________________ devel mailing list devel@lists.openchange.org http://mailman.openchange.org/listinfo/devel