2 Common conversion routines for exchange2ical
6 Copyright (C) Julien Kerihuel 2008
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program. If not, see <http://www.gnu.org/licenses/>.
22 #include "libexchange2ical/libexchange2ical.h"
25 static void exchange2ical_init(TALLOC_CTX *mem_ctx, struct exchange2ical *exchange2ical)
27 exchange2ical->TimeZoneStruct = NULL;
28 exchange2ical->TimeZoneDesc = NULL;
29 exchange2ical->method = ICAL_METHOD_NONE;
30 exchange2ical->vtimezone = NULL;
31 exchange2ical->vcalendar = NULL;
32 exchange2ical->mem_ctx = mem_ctx;
33 exchange2ical->partstat = ICAL_PARTSTAT_NONE;
34 exchange2ical->ResponseStatus = NULL;
35 exchange2ical->Recurring = NULL;
36 exchange2ical->RecurrencePattern = NULL;
37 exchange2ical->AppointmentRecurrencePattern = NULL;
38 exchange2ical->Keywords = NULL;
39 exchange2ical->Contacts = NULL;
40 exchange2ical->apptStateFlags = NULL;
41 exchange2ical->sensitivity = NULL;
42 exchange2ical->apptStartWhole = NULL;
43 exchange2ical->apptEndWhole = NULL;
44 exchange2ical->apptSubType = NULL;
45 exchange2ical->OwnerCriticalChange = NULL;
46 exchange2ical->body = NULL;
47 exchange2ical->LastModified = NULL;
48 exchange2ical->Location = NULL;
49 exchange2ical->Importance = NULL;
50 exchange2ical->ExceptionReplaceTime = NULL;
51 exchange2ical->ResponseRequested = NULL;
52 exchange2ical->NonSendableBcc = NULL;
53 exchange2ical->Sequence = NULL;
54 exchange2ical->Subject = NULL;
55 exchange2ical->MessageLocaleId = NULL;
56 exchange2ical->BusyStatus = NULL;
57 exchange2ical->IntendedBusyStatus = NULL;
58 exchange2ical->GlobalObjectId = NULL;
59 exchange2ical->AttendeeCriticalChange = NULL;
60 exchange2ical->OwnerApptId = NULL;
61 exchange2ical->apptReplyTime = NULL;
62 exchange2ical->NotAllowPropose = NULL;
63 exchange2ical->AllowExternCheck = NULL;
64 exchange2ical->apptLastSequence = NULL;
65 exchange2ical->apptSeqTime = NULL;
66 exchange2ical->AutoFillLocation = NULL;
67 exchange2ical->AutoStartCheck = NULL;
68 exchange2ical->CollaborateDoc = NULL;
69 exchange2ical->ConfCheck = NULL;
70 exchange2ical->ConfType = NULL;
71 exchange2ical->Directory = NULL;
72 exchange2ical->MWSURL = NULL;
73 exchange2ical->NetShowURL = NULL;
74 exchange2ical->OnlinePassword = NULL;
75 exchange2ical->OrgAlias = NULL;
76 exchange2ical->SenderName = NULL;
77 exchange2ical->SenderEmailAddress = NULL;
78 exchange2ical->ReminderSet = NULL;
79 exchange2ical->ReminderDelta = NULL;
80 exchange2ical->vevent = NULL;
81 exchange2ical->valarm = NULL;
82 exchange2ical->bodyHTML = NULL;
86 static void exchange2ical_clear(struct exchange2ical *exchange2ical)
88 if (exchange2ical->AppointmentRecurrencePattern){
89 talloc_free(exchange2ical->AppointmentRecurrencePattern);
92 if (exchange2ical->TimeZoneStruct) {
93 talloc_free(exchange2ical->TimeZoneStruct);
96 exchange2ical_init(exchange2ical->mem_ctx, exchange2ical);
100 static void exchange2ical_reset(struct exchange2ical *exchange2ical)
102 if (exchange2ical->AppointmentRecurrencePattern){
103 talloc_free(exchange2ical->AppointmentRecurrencePattern);
106 if (exchange2ical->TimeZoneStruct) {
107 talloc_free(exchange2ical->TimeZoneStruct);
110 exchange2ical->partstat = ICAL_PARTSTAT_NONE;
111 exchange2ical->ResponseStatus = NULL;
112 exchange2ical->Recurring = NULL;
113 exchange2ical->RecurrencePattern = NULL;
114 exchange2ical->AppointmentRecurrencePattern = NULL;
115 exchange2ical->Keywords = NULL;
116 exchange2ical->Contacts = NULL;
117 exchange2ical->apptStateFlags = NULL;
118 exchange2ical->sensitivity = NULL;
119 exchange2ical->apptStartWhole = NULL;
120 exchange2ical->apptEndWhole = NULL;
121 exchange2ical->apptSubType = NULL;
122 exchange2ical->OwnerCriticalChange = NULL;
123 exchange2ical->body = NULL;
124 exchange2ical->LastModified = NULL;
125 exchange2ical->Location = NULL;
126 exchange2ical->Importance = NULL;
127 exchange2ical->ExceptionReplaceTime = NULL;
128 exchange2ical->ResponseRequested = NULL;
129 exchange2ical->NonSendableBcc = NULL;
130 exchange2ical->Sequence = NULL;
131 exchange2ical->Subject = NULL;
132 exchange2ical->MessageLocaleId = NULL;
133 exchange2ical->BusyStatus = NULL;
134 exchange2ical->IntendedBusyStatus = NULL;
135 exchange2ical->GlobalObjectId = NULL;
136 exchange2ical->AttendeeCriticalChange = NULL;
137 exchange2ical->OwnerApptId = NULL;
138 exchange2ical->apptReplyTime = NULL;
139 exchange2ical->NotAllowPropose = NULL;
140 exchange2ical->AllowExternCheck = NULL;
141 exchange2ical->apptLastSequence = NULL;
142 exchange2ical->apptSeqTime = NULL;
143 exchange2ical->AutoFillLocation = NULL;
144 exchange2ical->AutoStartCheck = NULL;
145 exchange2ical->CollaborateDoc = NULL;
146 exchange2ical->ConfCheck = NULL;
147 exchange2ical->ConfType = NULL;
148 exchange2ical->Directory = NULL;
149 exchange2ical->MWSURL = NULL;
150 exchange2ical->NetShowURL = NULL;
151 exchange2ical->OnlinePassword = NULL;
152 exchange2ical->OrgAlias = NULL;
153 exchange2ical->SenderName = NULL;
154 exchange2ical->SenderEmailAddress = NULL;
155 exchange2ical->ReminderSet = NULL;
156 exchange2ical->ReminderDelta = NULL;
157 exchange2ical->vevent = NULL;
158 exchange2ical->valarm = NULL;
159 exchange2ical->bodyHTML = NULL;
160 exchange2ical->TimeZoneDesc = NULL;
161 exchange2ical->TimeZoneStruct = NULL;
165 static int exchange2ical_get_properties(TALLOC_CTX *mem_ctx, struct SRow *aRow, struct exchange2ical *exchange2ical, enum exchange2ical_flags eFlags)
167 struct Binary_r *apptrecur;
168 const char *messageClass;
169 struct Binary_r *TimeZoneStruct;
171 if(eFlags & VcalFlag){
172 messageClass = octool_get_propval(aRow, PR_MESSAGE_CLASS_UNICODE);
173 exchange2ical->method = get_ical_method(messageClass);
174 if (!exchange2ical->method) return -1;
177 if(((eFlags & RangeFlag) && !(eFlags & EntireFlag))||
178 (!(eFlags & RangeFlag) && (eFlags & EntireFlag))){
179 exchange2ical->apptStartWhole = (const struct FILETIME *)octool_get_propval(aRow, PidLidAppointmentStartWhole);
183 if(((eFlags & EventFlag) && !(eFlags & EntireFlag))||
184 (!(eFlags & EventFlag) && (eFlags & EntireFlag))){
185 exchange2ical->GlobalObjectId = (struct Binary_r *) octool_get_propval(aRow, PidLidGlobalObjectId);
186 exchange2ical->Sequence = (uint32_t *) octool_get_propval(aRow, PidLidAppointmentSequence);
190 if(((eFlags & EventsFlag) && !(eFlags & EntireFlag))||
191 (!(eFlags & EventsFlag) && (eFlags & EntireFlag))){
192 exchange2ical->GlobalObjectId = (struct Binary_r *) octool_get_propval(aRow, PidLidGlobalObjectId);
196 if(eFlags & EntireFlag) {
198 apptrecur = (struct Binary_r *) octool_get_propval(aRow, PidLidAppointmentRecur);
199 exchange2ical->AppointmentRecurrencePattern = get_AppointmentRecurrencePattern(mem_ctx,apptrecur);
200 exchange2ical->RecurrencePattern = &exchange2ical->AppointmentRecurrencePattern->RecurrencePattern;
202 TimeZoneStruct = (struct Binary_r *) octool_get_propval(aRow, PidLidTimeZoneStruct);
203 exchange2ical->TimeZoneStruct = get_TimeZoneStruct(mem_ctx, TimeZoneStruct);
205 exchange2ical->TimeZoneDesc = (const char *) octool_get_propval(aRow, PidLidTimeZoneDescription);
206 exchange2ical->Keywords = (const struct StringArray_r *) octool_get_propval(aRow, PidNameKeywords);
207 exchange2ical->Recurring = (uint8_t *) octool_get_propval(aRow, PidLidRecurring);
208 exchange2ical->TimeZoneDesc = (const char *) octool_get_propval(aRow, PidLidTimeZoneDescription);
209 exchange2ical->ExceptionReplaceTime = (const struct FILETIME *)octool_get_propval(aRow, PidLidExceptionReplaceTime);
210 exchange2ical->ResponseStatus = (uint32_t *) octool_get_propval(aRow, PidLidResponseStatus);
211 exchange2ical->apptStateFlags = (uint32_t *) octool_get_propval(aRow, PidLidAppointmentStateFlags);
212 exchange2ical->Contacts = (const struct StringArray_r *)octool_get_propval(aRow, PidLidContacts);
213 exchange2ical->apptEndWhole = (const struct FILETIME *)octool_get_propval(aRow, PidLidAppointmentEndWhole);
214 exchange2ical->apptSubType = (uint8_t *) octool_get_propval(aRow, PidLidAppointmentSubType);
215 exchange2ical->OwnerCriticalChange = (const struct FILETIME *)octool_get_propval(aRow, PidLidOwnerCriticalChange);
216 exchange2ical->Location = (const char *) octool_get_propval(aRow, PidLidLocation);
217 exchange2ical->NonSendableBcc = (const char *) octool_get_propval(aRow, PidLidNonSendableBcc);
218 exchange2ical->BusyStatus = (uint32_t *) octool_get_propval(aRow, PidLidBusyStatus);
219 exchange2ical->IntendedBusyStatus = (uint32_t *) octool_get_propval(aRow, PidLidIntendedBusyStatus);
220 exchange2ical->AttendeeCriticalChange = (const struct FILETIME *) octool_get_propval(aRow, PidLidAttendeeCriticalChange);
221 exchange2ical->apptReplyTime = (const struct FILETIME *)octool_get_propval(aRow, PidLidAppointmentReplyTime);
222 exchange2ical->NotAllowPropose = (uint8_t *) octool_get_propval(aRow, PidLidAppointmentNotAllowPropose);
223 exchange2ical->AllowExternCheck = (uint8_t *) octool_get_propval(aRow, PidLidAllowExternalCheck);
224 exchange2ical->apptLastSequence = (uint32_t *) octool_get_propval(aRow, PidLidAppointmentLastSequence);
225 exchange2ical->apptSeqTime = (const struct FILETIME *)octool_get_propval(aRow, PidLidAppointmentSequenceTime);
226 exchange2ical->AutoFillLocation = (uint8_t *) octool_get_propval(aRow, PidLidAutoFillLocation);
227 exchange2ical->AutoStartCheck = (uint8_t *) octool_get_propval(aRow, PidLidAutoStartCheck);
228 exchange2ical->CollaborateDoc = (const char *) octool_get_propval(aRow, PidLidCollaborateDoc);
229 exchange2ical->ConfCheck = (uint8_t *) octool_get_propval(aRow, PidLidConferencingCheck);
230 exchange2ical->ConfType = (uint32_t *) octool_get_propval(aRow, PidLidConferencingType);
231 exchange2ical->Directory = (const char *) octool_get_propval(aRow, PidLidDirectory);
232 exchange2ical->MWSURL = (const char *) octool_get_propval(aRow, PidLidMeetingWorkspaceUrl);
233 exchange2ical->NetShowURL = (const char *) octool_get_propval(aRow, PidLidNetShowUrl);
234 exchange2ical->OnlinePassword = (const char *) octool_get_propval(aRow, PidLidOnlinePassword);
235 exchange2ical->OrgAlias = (const char *) octool_get_propval(aRow, PidLidOrganizerAlias);
236 exchange2ical->ReminderSet = (uint8_t *) octool_get_propval(aRow, PidLidReminderSet);
237 exchange2ical->ReminderDelta = (uint32_t *) octool_get_propval(aRow, PidLidReminderDelta);
238 exchange2ical->sensitivity = (uint32_t *) octool_get_propval(aRow, PR_SENSITIVITY);
239 exchange2ical->created = (const struct FILETIME *)octool_get_propval(aRow, PR_CREATION_TIME);
240 exchange2ical->body = (const char *)octool_get_propval(aRow, PR_BODY_UNICODE);
241 exchange2ical->LastModified = (const struct FILETIME *)octool_get_propval(aRow, PR_LAST_MODIFICATION_TIME);
242 exchange2ical->Importance = (uint32_t *) octool_get_propval(aRow, PR_IMPORTANCE);
243 exchange2ical->ResponseRequested = (uint8_t *) octool_get_propval(aRow, PR_RESPONSE_REQUESTED);
244 exchange2ical->Subject = (const char *) octool_get_propval(aRow, PR_SUBJECT_UNICODE);
245 exchange2ical->MessageLocaleId = (uint32_t *) octool_get_propval(aRow, PR_MESSAGE_LOCALE_ID);
246 exchange2ical->OwnerApptId = (uint32_t *) octool_get_propval(aRow, PR_OWNER_APPT_ID);
247 exchange2ical->SenderName = (const char *) octool_get_propval(aRow, PR_SENDER_NAME);
248 exchange2ical->SenderEmailAddress = (const char *) octool_get_propval(aRow, PR_SENDER_EMAIL_ADDRESS);
256 static uint8_t exchange2ical_exception_from_ExceptionInfo(struct exchange2ical *exchange2ical, struct exchange2ical_check *exchange2ical_check)
260 icalparameter *param;
261 icaltimetype icaltime;
263 if(!exchange2ical->AppointmentRecurrencePattern) return 1;
264 if(!exchange2ical->AppointmentRecurrencePattern->ExceptionInfo) return 1;
265 if(!exchange2ical->AppointmentRecurrencePattern->ExceptionCount) return 1;
267 for(i=0; i<exchange2ical->AppointmentRecurrencePattern->ExceptionCount; i++) {
269 /*Check to see if event is acceptable*/
270 struct tm apptStart=get_tm_from_minutes_UTC(exchange2ical->AppointmentRecurrencePattern->ExceptionInfo->StartDateTime);
271 if (!checkEvent(exchange2ical, exchange2ical_check, &apptStart)){
275 /*Create a new vevent*/
276 exchange2ical->vevent = icalcomponent_new_vevent();
277 if ( ! (exchange2ical->vevent) ) {
280 icalcomponent_add_component(exchange2ical->vcalendar, exchange2ical->vevent);
282 /*dtstart from StartDateTime*/
283 if (exchange2ical->apptSubType && (*exchange2ical->apptSubType == 0x1)) {
285 tm = get_tm_from_minutes_UTC(exchange2ical->AppointmentRecurrencePattern->ExceptionInfo->StartDateTime);
286 icaltime= get_icaldate_from_tm(&tm);
287 prop = icalproperty_new_dtstart(icaltime);
288 icalcomponent_add_property(exchange2ical->vevent, prop);
290 if(exchange2ical->TimeZoneDesc){
292 tm = get_tm_from_minutes(exchange2ical->AppointmentRecurrencePattern->ExceptionInfo->StartDateTime);
293 icaltime= get_icaldate_from_tm(&tm);
294 prop = icalproperty_new_dtstart(icaltime);
295 icalcomponent_add_property(exchange2ical->vevent, prop);
296 param = icalparameter_new_tzid(exchange2ical->TimeZoneDesc);
297 icalproperty_add_parameter(prop, param);
300 tm = get_tm_from_minutes_UTC(exchange2ical->AppointmentRecurrencePattern->ExceptionInfo->StartDateTime);
301 icaltime= get_icaldate_from_tm(&tm);
302 prop = icalproperty_new_dtstart(icaltime);
303 icalcomponent_add_property(exchange2ical->vevent, prop);
306 /*dtend from EndDateTime*/
307 if (exchange2ical->apptSubType && (*exchange2ical->apptSubType == 0x1)) {
309 tm = get_tm_from_minutes_UTC(exchange2ical->AppointmentRecurrencePattern->ExceptionInfo->EndDateTime);
310 icaltime= get_icaldate_from_tm(&tm);
311 prop = icalproperty_new_dtend(icaltime);
312 icalcomponent_add_property(exchange2ical->vevent, prop);
314 if(exchange2ical->TimeZoneDesc){
316 tm = get_tm_from_minutes(exchange2ical->AppointmentRecurrencePattern->ExceptionInfo->EndDateTime);
317 icaltime= get_icaldate_from_tm(&tm);
318 prop = icalproperty_new_dtend(icaltime);
319 icalcomponent_add_property(exchange2ical->vevent, prop);
320 param = icalparameter_new_tzid(exchange2ical->TimeZoneDesc);
321 icalproperty_add_parameter(prop, param);
324 tm = get_tm_from_minutes_UTC(exchange2ical->AppointmentRecurrencePattern->ExceptionInfo->EndDateTime);
325 icaltime= get_icaldate_from_tm(&tm);
326 prop = icalproperty_new_dtend(icaltime);
327 icalcomponent_add_property(exchange2ical->vevent, prop);
330 /*recurrence-id from OriginalStartDate*/
331 if (exchange2ical->apptSubType && (*exchange2ical->apptSubType == 0x1)) {
333 tm = get_tm_from_minutes_UTC(exchange2ical->AppointmentRecurrencePattern->ExceptionInfo->OriginalStartDate);
334 icaltime= get_icaldate_from_tm(&tm);
335 prop = icalproperty_new_recurrenceid(icaltime);
336 icalcomponent_add_property(exchange2ical->vevent, prop);
338 if(exchange2ical->TimeZoneDesc){
340 tm = get_tm_from_minutes(exchange2ical->AppointmentRecurrencePattern->ExceptionInfo->OriginalStartDate);
341 icaltime= get_icaldate_from_tm(&tm);
342 prop = icalproperty_new_recurrenceid(icaltime);
343 icalcomponent_add_property(exchange2ical->vevent, prop);
344 param = icalparameter_new_tzid(exchange2ical->TimeZoneDesc);
345 icalproperty_add_parameter(prop, param);
348 tm = get_tm_from_minutes_UTC(exchange2ical->AppointmentRecurrencePattern->ExceptionInfo->OriginalStartDate);
349 icaltime= get_icaldate_from_tm(&tm);
350 prop = icalproperty_new_recurrenceid(icaltime);
351 icalcomponent_add_property(exchange2ical->vevent, prop);
355 /*summary from Subject if subject is set*/
356 if (exchange2ical->AppointmentRecurrencePattern->ExceptionInfo->OverrideFlags & 0x0001) {
357 exchange2ical->Subject=(const char *) &exchange2ical->AppointmentRecurrencePattern->ExceptionInfo->Subject.subject;
358 ical_property_SUMMARY(exchange2ical);
364 if(exchange2ical->AppointmentRecurrencePattern->ExceptionInfo->OverrideFlags & 0x0008){
365 exchange2ical->ReminderSet=(uint8_t *) &exchange2ical->AppointmentRecurrencePattern->ExceptionInfo->ReminderDelta.rSet;
367 if(exchange2ical->AppointmentRecurrencePattern->ExceptionInfo->OverrideFlags & 0x0004){
368 exchange2ical->ReminderDelta=&exchange2ical->AppointmentRecurrencePattern->ExceptionInfo->ReminderDelta.rDelta;
370 exchange2ical->ReminderDelta=NULL;
372 ical_component_VALARM(exchange2ical);
376 if(exchange2ical->AppointmentRecurrencePattern->ExceptionInfo->OverrideFlags & 0x0010){
377 exchange2ical->Location=(const char *) &exchange2ical->AppointmentRecurrencePattern->ExceptionInfo->Location.location;
378 ical_property_LOCATION(exchange2ical);
382 if(exchange2ical->AppointmentRecurrencePattern->ExceptionInfo->OverrideFlags & 0x0020){
383 exchange2ical->BusyStatus=&exchange2ical->AppointmentRecurrencePattern->ExceptionInfo->BusyStatus.bStatus;
384 ical_property_X_MICROSOFT_CDO_BUSYSTATUS(exchange2ical);
390 static uint8_t exchange2ical_exception_from_EmbeddedObj(struct exchange2ical *exchange2ical, struct exchange2ical_check *exchange2ical_check)
392 mapi_object_t obj_tb_attach;
393 mapi_object_t obj_attach;
394 struct SRowSet rowset_attach;
395 struct SPropTagArray *SPropTagArray;
396 const uint32_t *attach_num;
397 struct SPropValue *lpProps;
398 enum MAPISTATUS retval;
404 mapi_object_init(&obj_tb_attach);
405 retval = GetAttachmentTable(&exchange2ical->obj_message, &obj_tb_attach);
406 if (retval != MAPI_E_SUCCESS) {
409 SPropTagArray = set_SPropTagArray(exchange2ical->mem_ctx, 0x1, PR_ATTACH_NUM);
410 retval = SetColumns(&obj_tb_attach, SPropTagArray);
411 MAPIFreeBuffer(SPropTagArray);
412 retval = QueryRows(&obj_tb_attach, 0xa, TBL_ADVANCE, &rowset_attach);
414 for (i = 0; i < rowset_attach.cRows; i++) {
416 attach_num = (const uint32_t *)find_SPropValue_data(&(rowset_attach.aRow[i]), PR_ATTACH_NUM);
417 retval = OpenAttach(&exchange2ical->obj_message, *attach_num, &obj_attach);
419 if (retval != MAPI_E_SUCCESS) {
422 SPropTagArray = set_SPropTagArray(exchange2ical->mem_ctx, 0x3,
428 lpProps = talloc_zero(exchange2ical->mem_ctx, struct SPropValue);
429 retval = GetProps(&obj_attach, SPropTagArray, &lpProps, &count);
430 MAPIFreeBuffer(SPropTagArray);
431 if (retval != MAPI_E_SUCCESS) {
434 aRow2.ulAdrEntryPad = 0;
435 aRow2.cValues = count;
436 aRow2.lpProps = lpProps;
438 uint32_t *attachmentFlags;
439 uint32_t *attachMethod;
440 uint8_t *attachmentHidden;
442 attachmentFlags = (uint32_t *) octool_get_propval(&aRow2, PR_ATTACHMENT_FLAGS);
443 attachMethod = (uint32_t *) octool_get_propval(&aRow2, PR_ATTACH_METHOD);
444 attachmentHidden = (uint8_t *) octool_get_propval(&aRow2, PR_ATTACHMENT_HIDDEN);
446 if((*attachmentFlags & 0x00000002)
447 && (*attachMethod == 0x00000005)
448 && (attachmentHidden && (*attachmentHidden))) {
450 struct exchange2ical exception;
451 exchange2ical_init(exchange2ical->mem_ctx,&exception);
453 mapi_object_init(&exception.obj_message);
455 retval = OpenEmbeddedMessage(&obj_attach, &exception.obj_message, MAPI_READONLY);
456 if (retval != MAPI_E_SUCCESS) {
459 SPropTagArray = set_SPropTagArray(exchange2ical->mem_ctx, 0x2d,
460 PidLidFExceptionalBody,
462 PidLidAppointmentRecur,
463 PidLidAppointmentStateFlags,
464 PidLidTimeZoneDescription,
465 PidLidTimeZoneStruct,
466 PidLidAppointmentStartWhole,
467 PidLidAppointmentEndWhole,
468 PidLidAppointmentSubType,
469 PidLidOwnerCriticalChange,
471 PidLidExceptionReplaceTime,
472 PidLidNonSendableBcc,
473 PidLidAppointmentSequence,
475 PidLidIntendedBusyStatus,
476 PidLidCleanGlobalObjectId,
477 PidLidAttendeeCriticalChange,
478 PidLidAppointmentReplyTime,
479 PidLidAppointmentNotAllowPropose,
480 PidLidAllowExternalCheck,
481 PidLidAppointmentLastSequence,
482 PidLidAppointmentSequenceTime,
483 PidLidAutoFillLocation,
484 PidLidAutoStartCheck,
485 PidLidCollaborateDoc,
486 PidLidConferencingCheck,
487 PidLidConferencingType,
490 PidLidOnlinePassword,
491 PidLidOrganizerAlias,
494 PR_MESSAGE_CLASS_UNICODE,
497 PR_LAST_MODIFICATION_TIME,
499 PR_RESPONSE_REQUESTED,
503 PR_SENDER_EMAIL_ADDRESS,
509 retval = GetProps(&exception.obj_message, SPropTagArray, &lpProps, &count);
511 if (retval == MAPI_E_SUCCESS) {
512 aRow2.ulAdrEntryPad = 0;
513 aRow2.cValues = count;
514 aRow2.lpProps = lpProps;
517 /*Get required properties to check if right event*/
518 exchange2ical_get_properties(exchange2ical->mem_ctx, &aRow2, &exception, exchange2ical_check->eFlags);
520 /*Check to see if event is acceptable*/
521 if (!checkEvent(&exception, exchange2ical_check, get_tm_from_FILETIME(exception.apptStartWhole))){
525 /*Grab Rest of Properties*/
526 exchange2ical_get_properties(exchange2ical->mem_ctx, &aRow2, &exception, exchange2ical_check->eFlags | EntireFlag);
527 uint8_t *dBody = (uint8_t *) octool_get_propval(&aRow2, PidLidFExceptionalBody);
528 retval = GetRecipientTable(&exception.obj_message,
529 &exception.Recipients.SRowSet,
530 &exception.Recipients.SPropTagArray);
532 /*Check for set subject*/
533 if (!exception.Subject){
534 exception.Subject=exchange2ical->Subject;
536 /*Check for a set apptSubType*/
537 if (!exception.apptSubType){
538 exception.apptSubType=exchange2ical->apptSubType;
540 /*check for a set Location*/
541 if (!exception.Location){
542 exception.Location=exchange2ical->Location;
544 /*check for set valarm info*/
545 if(!exception.ReminderSet){
546 exception.ReminderSet=exchange2ical->ReminderSet;
548 if(!exception.ReminderDelta){
549 exception.ReminderDelta=exchange2ical->ReminderDelta;
552 /*Set to same vcalendar as parent*/
553 exception.vcalendar=exchange2ical->vcalendar;
555 /*Set to same uid fallback in case GlobalObjId is missing*/
556 exception.idx=exchange2ical->idx;
559 /*has a modified summary*/
561 SPropTagArray = set_SPropTagArray(exchange2ical->mem_ctx, 0x1, PR_BODY_HTML_UNICODE);
562 retval = GetProps(&exception.obj_message, SPropTagArray, &lpProps, &count);
563 MAPIFreeBuffer(SPropTagArray);
564 if (retval == MAPI_E_SUCCESS) {
565 aRowT.ulAdrEntryPad = 0;
566 aRowT.cValues = count;
567 aRowT.lpProps = lpProps;
568 exception.bodyHTML = (const char *)octool_get_propval(&aRowT, PR_BODY_HTML_UNICODE);
570 /* has the same summary as parent*/
572 exception.body=exchange2ical->body;
573 exception.bodyHTML=exchange2ical->bodyHTML;
576 ical_component_VEVENT(&exception);
577 exception.vcalendar=NULL;
578 exchange2ical_clear(&exception);
581 mapi_object_release(&exception.obj_message);
583 MAPIFreeBuffer(lpProps);
590 mapi_object_release(&obj_tb_attach);
594 icalcomponent * _Exchange2Ical(mapi_object_t *obj_folder, struct exchange2ical_check *exchange2ical_check)
597 enum MAPISTATUS retval;
599 struct SRowSet SRowSet;
602 struct SPropValue *lpProps;
603 struct SPropTagArray *SPropTagArray = NULL;
604 struct exchange2ical exchange2ical;
605 mapi_object_t obj_table;
609 mem_ctx = talloc_named(NULL, 0, "exchange2ical");
610 exchange2ical_init(mem_ctx, &exchange2ical);
612 /* Open the contents table */
613 mapi_object_init(&obj_table);
614 retval = GetContentsTable(obj_folder, &obj_table, 0, &count);
615 if (retval != MAPI_E_SUCCESS){
616 talloc_free(mem_ctx);
620 DEBUG(0, ("MAILBOX (%d appointments)\n", count));
622 talloc_free(mem_ctx);
626 SPropTagArray = set_SPropTagArray(mem_ctx, 0x2,
630 retval = SetColumns(&obj_table, SPropTagArray);
631 MAPIFreeBuffer(SPropTagArray);
632 if (retval != MAPI_E_SUCCESS) {
633 mapi_errstr("SetColumns", retval);
634 talloc_free(mem_ctx);
638 while ((retval = QueryRows(&obj_table, count, TBL_ADVANCE, &SRowSet)) != MAPI_E_NOT_FOUND && SRowSet.cRows) {
639 count -= SRowSet.cRows;
640 for (i = (SRowSet.cRows-1); i >= 0; i--) {
641 mapi_object_init(&exchange2ical.obj_message);
642 retval = OpenMessage(obj_folder,
643 SRowSet.aRow[i].lpProps[0].value.d,
644 SRowSet.aRow[i].lpProps[1].value.d,
645 &exchange2ical.obj_message, 0);
646 if (retval != MAPI_E_NOT_FOUND) {
647 SPropTagArray = set_SPropTagArray(mem_ctx, 0x30,
648 PidLidGlobalObjectId,
651 PidLidAppointmentRecur,
652 PidLidAppointmentStateFlags,
653 PidLidTimeZoneDescription,
654 PidLidTimeZoneStruct,
656 PidLidAppointmentStartWhole,
657 PidLidAppointmentEndWhole,
658 PidLidAppointmentSubType,
659 PidLidOwnerCriticalChange,
661 PidLidNonSendableBcc,
662 PidLidAppointmentSequence,
664 PidLidIntendedBusyStatus,
665 PidLidAttendeeCriticalChange,
666 PidLidAppointmentReplyTime,
667 PidLidAppointmentNotAllowPropose,
668 PidLidAllowExternalCheck,
669 PidLidAppointmentLastSequence,
670 PidLidAppointmentSequenceTime,
671 PidLidAutoFillLocation,
672 PidLidAutoStartCheck,
673 PidLidCollaborateDoc,
674 PidLidConferencingCheck,
675 PidLidConferencingType,
677 PidLidMeetingWorkspaceUrl,
679 PidLidOnlinePassword,
680 PidLidOrganizerAlias,
683 PidLidResponseStatus,
684 PR_MESSAGE_CLASS_UNICODE,
688 PR_LAST_MODIFICATION_TIME,
690 PR_RESPONSE_REQUESTED,
694 PR_SENDER_EMAIL_ADDRESS,
699 retval = GetProps(&exchange2ical.obj_message, SPropTagArray, &lpProps, &count);
701 MAPIFreeBuffer(SPropTagArray);
703 if (retval == MAPI_E_SUCCESS) {
704 aRow.ulAdrEntryPad = 0;
705 aRow.cValues = count;
706 aRow.lpProps = lpProps;
708 /*Get Vcal info if first event*/
709 if(i==(SRowSet.cRows-1)){
710 ret = exchange2ical_get_properties(mem_ctx, &aRow, &exchange2ical, VcalFlag);
711 /*TODO: exit nicely*/
712 ical_component_VCALENDAR(&exchange2ical);
716 /*Get required properties to check if right event*/
717 ret = exchange2ical_get_properties(mem_ctx, &aRow, &exchange2ical, exchange2ical_check->eFlags);
719 /*Check to see if event is acceptable*/
720 if (!checkEvent(&exchange2ical, exchange2ical_check, get_tm_from_FILETIME(exchange2ical.apptStartWhole))){
724 /*Set RecipientTable*/
725 retval = GetRecipientTable(&exchange2ical.obj_message,
726 &exchange2ical.Recipients.SRowSet,
727 &exchange2ical.Recipients.SPropTagArray);
729 /*Set PR_BODY_HTML for x_alt_desc property*/
730 SPropTagArray = set_SPropTagArray(mem_ctx, 0x1, PR_BODY_HTML_UNICODE);
731 retval = GetProps(&exchange2ical.obj_message, SPropTagArray, &lpProps, &count);
732 MAPIFreeBuffer(SPropTagArray);
733 if (retval == MAPI_E_SUCCESS) {
734 aRowT.ulAdrEntryPad = 0;
735 aRowT.cValues = count;
736 aRowT.lpProps = lpProps;
737 exchange2ical.bodyHTML = (const char *)octool_get_propval(&aRowT, PR_BODY_HTML_UNICODE);
740 /*Get rest of properties*/
741 ret = exchange2ical_get_properties(mem_ctx, &aRow, &exchange2ical, (exchange2ical_check->eFlags | EntireFlag));
744 ical_component_VEVENT(&exchange2ical);
746 /*Exceptions to event*/
747 if(exchange2ical_check->eFlags != EventFlag){
748 ret = exchange2ical_exception_from_EmbeddedObj(&exchange2ical, exchange2ical_check);
750 ret=exchange2ical_exception_from_ExceptionInfo(&exchange2ical, exchange2ical_check);
754 /*REMOVE once globalobjid is fixed*/
757 MAPIFreeBuffer(lpProps);
758 exchange2ical_reset(&exchange2ical);
762 mapi_object_release(&exchange2ical.obj_message);
766 icalcomponent *icalendar = exchange2ical.vcalendar;
767 exchange2ical_clear(&exchange2ical);
769 /* Uninitialize MAPI subsystem */
770 mapi_object_release(&obj_table);
771 talloc_free(mem_ctx);