Merge r3881,3893,3894,3895,3907,3908,3910,3911,3912,3913,3915,3916,3917,3919,3920...
[jelmer/openchange.git] / utils / mapitest / modules / module_oxcmsg.c
1 /*
2    Stand-alone MAPI testsuite
3
4    OpenChange Project - E-MAIL OBJECT PROTOCOL operations
5
6    Copyright (C) Julien Kerihuel 2008
7    Copyright (C) Brad Hards <bradh@openchange.org> 2009
8
9    This program is free software; you can redistribute it and/or modify
10    it under the terms of the GNU General Public License as published by
11    the Free Software Foundation; either version 3 of the License, or
12    (at your option) any later version.
13    
14    This program is distributed in the hope that it will be useful,
15    but WITHOUT ANY WARRANTY; without even the implied warranty of
16    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17    GNU General Public License for more details.
18    
19    You should have received a copy of the GNU General Public License
20    along with this program.  If not, see <http://www.gnu.org/licenses/>.
21 */
22
23 #include "utils/mapitest/mapitest.h"
24 #include "utils/mapitest/proto.h"
25
26 /**
27    \file module_oxcmsg.c
28
29    \brief Message and Attachment Object Protocol test suite
30 */
31
32
33 /**
34    \details Test the CreateMessage (0x6) operation
35
36    This function:
37         -# Log on the user private mailbox
38         -# Open the Outbox folder
39         -# Create the message
40         -# Delete the message
41
42    \param mt pointer on the top-level mapitest structure
43
44    \return true on success, otherwise false
45  */
46 _PUBLIC_ bool mapitest_oxcmsg_CreateMessage(struct mapitest *mt)
47 {
48         bool                    ret;
49         mapi_object_t           obj_store;
50         mapi_object_t           obj_folder;
51         mapi_object_t           obj_message;
52         mapi_id_t               id_msgs[1];
53
54         /* Step 1. Logon */
55         mapi_object_init(&obj_store);
56         OpenMsgStore(mt->session, &obj_store);
57         mapitest_print_retval(mt, "OpenMsgStore");
58         if (GetLastError() != MAPI_E_SUCCESS) {
59                 return false;
60         }
61
62         /* Step 2. Open Outbox folder */
63         mapi_object_init(&obj_folder);
64         ret = mapitest_common_folder_open(mt, &obj_store, &obj_folder, olFolderOutbox);
65         if (ret == false) return ret;
66
67         /* Step 3. Create the message */
68         mapi_object_init(&obj_message);
69         CreateMessage(&obj_folder, &obj_message);
70         mapitest_print_retval(mt, "CreateMessage");
71         if (GetLastError() != MAPI_E_SUCCESS) {
72                 return false;
73         }
74
75         /* Step 4. Delete the message */
76         id_msgs[0] = mapi_object_get_id(&obj_message);
77         DeleteMessage(&obj_folder, id_msgs, 1);
78         mapitest_print_retval(mt, "DeleteMessage");
79         if (GetLastError() != MAPI_E_SUCCESS) {
80                 return false;
81         }
82
83         /* Release */
84         mapi_object_release(&obj_message);
85         mapi_object_release(&obj_folder);
86         mapi_object_release(&obj_store);
87
88         return true;
89 }
90
91 #define OXCMSG_SETREADFLAGS     "[OXCMSG] SetMessageReadFlag"
92
93 /**
94    \details Test the SetMessageReadFlag (0x11) operation
95
96    This function:
97         -# Log on the user private mailbox
98         -# Open the Inbox folder
99         -# Create a tmp message
100         -# Play with SetMessageReadFlag
101         -# Delete the message
102         
103    Note: We can test either SetMessageReadFlag was effective by checking its
104    old/new value with GetProps on PR_MESSAGE_FLAGS property.
105
106
107    \param mt pointer on the top-level mapitest structure
108
109    \return true on success, otherwise false
110  */
111 _PUBLIC_ bool mapitest_oxcmsg_SetMessageReadFlag(struct mapitest *mt)
112 {
113         bool                    ret;
114         mapi_object_t           obj_store;
115         mapi_object_t           obj_folder;
116         mapi_object_t           obj_message;
117         struct SPropTagArray    *SPropTagArray;
118         struct SPropValue       *lpProps;
119         uint32_t                cValues;
120         mapi_id_t               id_msgs[1];
121         uint32_t                status= 0;
122
123         /* Step 1. Logon */
124         mapi_object_init(&obj_store);
125         OpenMsgStore(mt->session, &obj_store);
126         mapitest_print_retval(mt, "OpenMsgStore");
127         if (GetLastError() != MAPI_E_SUCCESS) {
128                 return false;
129         }
130         
131         /* Step 2. Open Outbox folder */
132         mapi_object_init(&obj_folder);
133         ret = mapitest_common_folder_open(mt, &obj_store, &obj_folder, olFolderOutbox);
134         if (ret == false) return ret;
135
136         /* Step 3. Create the tmp message and save it */
137         mapi_object_init(&obj_message);
138         ret = mapitest_common_message_create(mt, &obj_folder, &obj_message, OXCMSG_SETREADFLAGS);
139         if (ret == false) return ret;
140
141         SaveChangesMessage(&obj_folder, &obj_message, KeepOpenReadWrite);
142         mapitest_print_retval(mt, "SaveChangesMessage");
143         if (GetLastError() != MAPI_E_SUCCESS) {
144                 return false;
145         }
146
147         /* Step 4. Play with SetMessageReadFlag */
148         SPropTagArray = set_SPropTagArray(mt->mem_ctx, 0x2, PR_MID, PR_MESSAGE_FLAGS);
149         ret = true;
150
151         /* 1. Retrieve and Save the original PR_MESSAGE_FLAGS value */
152         GetProps(&obj_message, 0, SPropTagArray, &lpProps, &cValues);
153         if (GetLastError() != MAPI_E_SUCCESS) {
154                 return false;
155         }
156
157         if (cValues > 1) {
158                 status = lpProps[1].value.l;
159         }
160         MAPIFreeBuffer(lpProps);
161         
162         /* Set message flags as read */
163         SetMessageReadFlag(&obj_folder, &obj_message, MSGFLAG_READ);
164         mapitest_print_retval_fmt(mt, "SetMessageReadFlag", "(%s)", "MSGFLAG_READ");
165
166         /* Check if the operation was successful */
167         GetProps(&obj_message, 0, SPropTagArray, &lpProps, &cValues);
168         mapitest_print_retval(mt, "GetProps");
169         if (GetLastError() != MAPI_E_SUCCESS) {
170                 return false;
171         }
172
173         if (cValues > 1 && status != lpProps[1].value.l) {
174                 mapitest_print(mt, "* %-35s: PR_MESSAGE_FLAGS changed\n", "SetMessageReadFlag");
175                 status = lpProps[1].value.l;
176         } else {
177                 mapitest_print(mt, "* %-35s: PR_MESSAGE_FLAGS failed\n", "SetMessageReadFlag");
178                 return false;
179         }
180         MAPIFreeBuffer(lpProps);
181                 
182         /* Set the message flags as submitted */
183         SetMessageReadFlag(&obj_folder, &obj_message, MSGFLAG_SUBMIT);
184         mapitest_print_retval_fmt(mt, "SetMessageReadFlag", "(%s)", "MSGFLAG_SUBMIT");
185         
186         /* Check if the operation was successful */
187         GetProps(&obj_message, 0, SPropTagArray, &lpProps, &cValues);
188         if (GetLastError() != MAPI_E_SUCCESS) {
189                 return false;
190         }
191
192         if (cValues > 1 && status != lpProps[1].value.l) {
193                 mapitest_print(mt, "* %-35s: PR_MESSAGE_FLAGS changed\n", "SetMessageReadFlag");
194                 status = lpProps[1].value.l;
195         } else {
196                 mapitest_print(mt, "* %-35s: PR_MESSAGE_FLAGS failed\n", "SetMessageReadFlag");
197                 return false;
198         }
199
200         /* Step 5. Delete the message */
201         id_msgs[0] = mapi_object_get_id(&obj_message);
202         DeleteMessage(&obj_folder, id_msgs, 1);
203         mapitest_print_retval(mt, "DeleteMessage");
204         if (GetLastError() != MAPI_E_SUCCESS) {
205                 return false;
206         }
207         
208         /* Release */
209         mapi_object_release(&obj_message);
210         mapi_object_release(&obj_folder);
211         mapi_object_release(&obj_store);
212
213         MAPIFreeBuffer(SPropTagArray);
214
215         return true;
216 }
217
218 /**
219    \details Test the ModifyRecipients (0xe) operation
220
221    This function:
222    -# Log on the user private mailbox
223    -# Open the Outbox folder
224    -# Create the message
225    -# Resolve recipients names
226    -# Call ModifyRecipients operation for MAPI_TO, MAPI_CC, MAPI_BCC
227    -# Delete the message
228
229    \param mt pointer on the top-level mapitest structure
230
231    \return true on success, otherwise false
232  */
233 _PUBLIC_ bool mapitest_oxcmsg_ModifyRecipients(struct mapitest *mt)
234 {
235         enum MAPISTATUS                 retval;
236         mapi_object_t                   obj_store;
237         mapi_object_t                   obj_folder;
238         mapi_object_t                   obj_message;
239         mapi_id_t                       id_folder;
240         char                            **username = NULL;
241         struct SPropTagArray            *SPropTagArray = NULL;
242         struct PropertyValue_r          value;
243         struct PropertyRowSet_r         *RowSet = NULL;
244         struct SRowSet                  *SRowSet = NULL;
245         struct PropertyTagArray_r       *flaglist = NULL;
246         mapi_id_t                       id_msgs[1];
247
248         /* Step 1. Logon */
249         mapi_object_init(&obj_store);
250         retval = OpenMsgStore(mt->session, &obj_store);
251         mapitest_print_retval(mt, "OpenMsgStore");
252         if (GetLastError() != MAPI_E_SUCCESS) {
253                 return false;
254         }
255
256         /* Step 2. Open Outbox folder */
257         retval = GetDefaultFolder(&obj_store, &id_folder, olFolderOutbox);
258         mapitest_print_retval(mt, "GetDefaultFolder");
259         if (GetLastError() != MAPI_E_SUCCESS) {
260                 return false;
261         }
262
263         mapi_object_init(&obj_folder);
264         retval = OpenFolder(&obj_store, id_folder, &obj_folder);
265         mapitest_print_retval(mt, "OpenFolder");
266         if (GetLastError() != MAPI_E_SUCCESS) {
267                 return false;
268         }
269
270         /* Step 3. Create the message */
271         mapi_object_init(&obj_message);
272         retval = CreateMessage(&obj_folder, &obj_message);
273         mapitest_print_retval(mt, "CreateMessage");
274         if (GetLastError() != MAPI_E_SUCCESS) {
275                 return false;
276         }
277
278
279         /* Step 4. Resolve the recipients and call ModifyRecipients */
280         SPropTagArray = set_SPropTagArray(mt->mem_ctx, 0xA,
281                                           PR_ENTRYID,
282                                           PR_DISPLAY_NAME_UNICODE,
283                                           PR_OBJECT_TYPE,
284                                           PR_DISPLAY_TYPE,
285                                           PR_TRANSMITTABLE_DISPLAY_NAME_UNICODE,
286                                           PR_EMAIL_ADDRESS_UNICODE,
287                                           PR_ADDRTYPE_UNICODE,
288                                           PR_SEND_RICH_INFO,
289                                           PR_7BIT_DISPLAY_NAME_UNICODE,
290                                           PR_SMTP_ADDRESS_UNICODE);
291
292         username = talloc_array(mt->mem_ctx, char *, 2);
293         username[0] = (char *)mt->profile->mailbox;
294         username[1] = NULL;
295
296         retval = ResolveNames(mapi_object_get_session(&obj_message), 
297                               (const char **)username, SPropTagArray, 
298                               &RowSet, &flaglist, MAPI_UNICODE);
299         mapitest_print_retval_clean(mt, "ResolveNames", retval);
300         if (retval != MAPI_E_SUCCESS) {
301                 return false;
302         }
303
304         if (!RowSet) {
305                 mapitest_print(mt, "Null RowSet\n");
306                 return false;
307         }
308         if (!RowSet->cRows) {
309                 mapitest_print(mt, "No values in RowSet\n");
310                 MAPIFreeBuffer(RowSet);
311                 return false;
312         }
313
314         value.ulPropTag = PR_SEND_INTERNET_ENCODING;
315         value.value.l = 0;
316         PropertyRowSet_propcpy(mt->mem_ctx, RowSet, value);
317
318         SRowSet = talloc_zero(RowSet, struct SRowSet);
319         cast_PropertyRowSet_to_SRowSet(SRowSet, RowSet, SRowSet);
320
321         SetRecipientType(&(SRowSet->aRow[0]), MAPI_TO);
322         mapitest_print_retval(mt, "SetRecipientType");
323         retval = ModifyRecipients(&obj_message, SRowSet);
324         mapitest_print_retval_fmt(mt, "ModifyRecipients", "(%s)", "MAPI_TO");
325         if (retval != MAPI_E_SUCCESS) {
326                 MAPIFreeBuffer(RowSet);
327                 MAPIFreeBuffer(flaglist);
328                 return false;
329         }
330
331         SetRecipientType(&(SRowSet->aRow[0]), MAPI_CC);
332         mapitest_print_retval(mt, "SetRecipientType");
333         retval = ModifyRecipients(&obj_message, SRowSet);
334         mapitest_print_retval_fmt(mt, "ModifyRecipients", "(%s)", "MAPI_CC");
335         if (retval != MAPI_E_SUCCESS) {
336                 MAPIFreeBuffer(RowSet);
337                 MAPIFreeBuffer(flaglist);
338                 return false;
339         }
340
341
342         SetRecipientType(&(SRowSet->aRow[0]), MAPI_BCC);
343         mapitest_print_retval(mt, "SetRecipientType");
344         retval = ModifyRecipients(&obj_message, SRowSet);
345         mapitest_print_retval_fmt(mt, "ModifyRecipients", "(%s)", "MAPI_BCC");
346         if (retval != MAPI_E_SUCCESS) {
347                 MAPIFreeBuffer(RowSet);
348                 MAPIFreeBuffer(flaglist);
349                 return false;
350         }
351
352         /* Step 5. Delete the message */
353         id_msgs[0] = mapi_object_get_id(&obj_message);
354         retval = DeleteMessage(&obj_folder, id_msgs, 1);
355         mapitest_print_retval(mt, "DeleteMessage");
356         if (retval != MAPI_E_SUCCESS) {
357                 MAPIFreeBuffer(RowSet);
358                 MAPIFreeBuffer(flaglist);
359                 return false;
360         }
361         /* Release */
362         MAPIFreeBuffer(RowSet);
363         MAPIFreeBuffer(flaglist);
364         mapi_object_release(&obj_message);
365         mapi_object_release(&obj_folder);
366         mapi_object_release(&obj_store);
367
368         return true;
369 }
370
371
372 /**
373    \details Test the RemoveAllRecipients (0xd) operation
374
375    This function:
376    -# Log on the use private mailbox
377    -# Open the Outbox folder
378    -# Create the message, set recipients
379    -# Save the message
380    -# Remove all recipients
381    -# Delete the message
382
383    \param mt point on the top-level mapitest structure
384    
385    \return true on success, otherwise false
386  */
387 _PUBLIC_ bool mapitest_oxcmsg_RemoveAllRecipients(struct mapitest *mt)
388 {
389         enum MAPISTATUS                 retval;
390         bool                            ret = false;
391         mapi_object_t                   obj_store;
392         mapi_object_t                   obj_folder;
393         mapi_object_t                   obj_message;
394         mapi_id_t                       id_folder;
395         char                            **username = NULL;
396         struct SPropTagArray            *SPropTagArray = NULL;
397         struct PropertyValue_r          value;
398         struct PropertyRowSet_r         *RowSet = NULL;
399         struct SRowSet                  *SRowSet = NULL;
400         struct PropertyTagArray_r       *flaglist = NULL;
401         mapi_id_t                       id_msgs[1];
402
403         /* Step 1. Logon */
404         mapi_object_init(&obj_store);
405         retval = OpenMsgStore(mt->session, &obj_store);
406         mapitest_print_retval(mt, "OpenMsgStore");
407         if (GetLastError() != MAPI_E_SUCCESS) {
408                 return false;
409         }
410
411         /* Step 2. Open Outbox folder */
412         retval = GetDefaultFolder(&obj_store, &id_folder, olFolderInbox);
413         mapitest_print_retval(mt, "GetDefaultFolder");
414         if (GetLastError() != MAPI_E_SUCCESS) {
415                 return false;
416         }
417
418         mapi_object_init(&obj_folder);
419         retval = OpenFolder(&obj_store, id_folder, &obj_folder);
420         mapitest_print_retval(mt, "OpenFolder");
421         if (GetLastError() != MAPI_E_SUCCESS) {
422                 return false;
423         }
424
425         /* Step 3. Create the message */
426         mapi_object_init(&obj_message);
427         retval = CreateMessage(&obj_folder, &obj_message);
428         mapitest_print_retval(mt, "CreateMessage");
429         if (GetLastError() != MAPI_E_SUCCESS) {
430                 return false;
431         }
432
433         SPropTagArray = set_SPropTagArray(mt->mem_ctx, 0xA,
434                                           PR_ENTRYID,
435                                           PR_DISPLAY_NAME_UNICODE,
436                                           PR_OBJECT_TYPE,
437                                           PR_DISPLAY_TYPE,
438                                           PR_TRANSMITTABLE_DISPLAY_NAME_UNICODE,
439                                           PR_EMAIL_ADDRESS_UNICODE,
440                                           PR_ADDRTYPE_UNICODE,
441                                           PR_SEND_RICH_INFO,
442                                           PR_7BIT_DISPLAY_NAME_UNICODE,
443                                           PR_SMTP_ADDRESS_UNICODE);
444
445         username = talloc_array(mt->mem_ctx, char *, 2);
446         username[0] = (char *)mt->profile->mailbox;
447         username[1] = NULL;
448
449         retval = ResolveNames(mapi_object_get_session(&obj_message),
450                               (const char **)username, SPropTagArray, 
451                               &RowSet, &flaglist, MAPI_UNICODE);
452         mapitest_print_retval_clean(mt, "ResolveNames", retval);
453         if (retval != MAPI_E_SUCCESS) {
454                 return false;
455         }
456         if (!RowSet) {
457                 mapitest_print(mt, "Null RowSet\n");
458                 return false;
459         }
460         if (!RowSet->cRows) {
461                 mapitest_print(mt, "No values in RowSet\n");
462                 MAPIFreeBuffer(RowSet);
463                 return false;
464         }
465
466         value.ulPropTag = PR_SEND_INTERNET_ENCODING;
467         value.value.l = 0;
468         PropertyRowSet_propcpy(mt->mem_ctx, RowSet, value);
469
470         SRowSet = talloc_zero(RowSet, struct SRowSet);
471         cast_PropertyRowSet_to_SRowSet(SRowSet, RowSet, SRowSet);
472
473         SetRecipientType(&(SRowSet->aRow[0]), MAPI_TO);
474         retval = ModifyRecipients(&obj_message, SRowSet);
475         mapitest_print_retval_fmt(mt, "ModifyRecipients", "(%s)", "MAPI_TO");
476         if (GetLastError() != MAPI_E_SUCCESS) {
477                 MAPIFreeBuffer(RowSet);
478                 MAPIFreeBuffer(flaglist);
479                 return false;
480         }
481
482         SetRecipientType(&(SRowSet->aRow[0]), MAPI_CC);
483         retval = ModifyRecipients(&obj_message, SRowSet);
484         mapitest_print_retval_fmt(mt, "ModifyRecipients", "(%s)", "MAPI_CC");
485         if (GetLastError() != MAPI_E_SUCCESS) {
486                 MAPIFreeBuffer(RowSet);
487                 MAPIFreeBuffer(flaglist);
488                 return false;
489         }
490
491
492         SetRecipientType(&(SRowSet->aRow[0]), MAPI_BCC);
493         retval = ModifyRecipients(&obj_message, SRowSet);
494         mapitest_print_retval_fmt(mt, "ModifyRecipients", "(%s)", "MAPI_BCC");
495         if (GetLastError() != MAPI_E_SUCCESS) {
496                 MAPIFreeBuffer(RowSet);
497                 MAPIFreeBuffer(flaglist);
498                 return false;
499         }
500
501         ret = true;
502
503         /* Step 4. Remove all recipients */
504         retval = RemoveAllRecipients(&obj_message);
505         mapitest_print_retval(mt, "RemoveAllRecipients");
506         if (GetLastError() != MAPI_E_SUCCESS) {
507                 MAPIFreeBuffer(RowSet);
508                 MAPIFreeBuffer(flaglist);
509                 ret = false;
510         }
511
512         /* Step 5. Save the message */
513         retval = SaveChangesMessage(&obj_folder, &obj_message, KeepOpenReadOnly);
514         mapitest_print_retval(mt, "SaveChangesMessage");
515         if (GetLastError() != MAPI_E_SUCCESS) {
516                 MAPIFreeBuffer(RowSet);
517                 MAPIFreeBuffer(flaglist);
518                 return false;
519         }
520
521         /* Step 6. Delete the message */
522         errno = 0;
523         id_msgs[0] = mapi_object_get_id(&obj_message);
524         retval = DeleteMessage(&obj_folder, id_msgs, 1);
525         mapitest_print_retval(mt, "DeleteMessage");
526         if (GetLastError() != MAPI_E_SUCCESS) {
527                 MAPIFreeBuffer(RowSet);
528                 MAPIFreeBuffer(flaglist);
529                 ret = false;
530         }
531
532         /* Release */
533         MAPIFreeBuffer(RowSet);
534         MAPIFreeBuffer(flaglist);
535         mapi_object_release(&obj_message);
536         mapi_object_release(&obj_folder);
537         mapi_object_release(&obj_store);
538
539         return ret;
540 }
541
542
543 /**
544    \details Test the ReadRecipients (0xf) operation
545
546       This function:
547       -# Log on the use private mailbox
548       -# Open the Outbox folder
549       -# Create the message, set recipients
550       -# Save the message
551       -# Read message recipients
552       -# Delete the message
553
554    \param mt point on the top-level mapitest structure
555    
556    \return true on success, otherwise false
557  */
558 _PUBLIC_ bool mapitest_oxcmsg_ReadRecipients(struct mapitest *mt)
559 {
560         enum MAPISTATUS                 retval;
561         mapi_object_t                   obj_store;
562         mapi_object_t                   obj_folder;
563         mapi_object_t                   obj_message;
564         mapi_id_t                       id_folder;
565         char                            **username = NULL;
566         struct SPropTagArray            *SPropTagArray = NULL;
567         struct PropertyValue_r          value;
568         struct PropertyRowSet_r         *RowSet = NULL;
569         struct SRowSet                  *SRowSet = NULL;
570         struct PropertyTagArray_r       *flaglist = NULL;
571         struct ReadRecipientRow         *RecipientRows;
572         uint8_t                         count;
573         mapi_id_t                       id_msgs[1];
574
575         /* Step 1. Logon */
576         mapi_object_init(&obj_store);
577         retval = OpenMsgStore(mt->session, &obj_store);
578         mapitest_print_retval(mt, "OpenMsgStore");
579         if (GetLastError() != MAPI_E_SUCCESS) {
580                 return false;
581         }
582
583         /* Step 2. Open Outbox folder */
584         retval = GetDefaultFolder(&obj_store, &id_folder, olFolderInbox);
585         mapitest_print_retval(mt, "GetDefaultFolder");
586         if (GetLastError() != MAPI_E_SUCCESS) {
587                 return false;
588         }
589
590         mapi_object_init(&obj_folder);
591         retval = OpenFolder(&obj_store, id_folder, &obj_folder);
592         mapitest_print_retval(mt, "OpenFolder");
593         if (GetLastError() != MAPI_E_SUCCESS) {
594                 return false;
595         }
596
597         /* Step 3. Create the message */
598         mapi_object_init(&obj_message);
599         retval = CreateMessage(&obj_folder, &obj_message);
600         mapitest_print_retval(mt, "CreateMessage");
601         if (GetLastError() != MAPI_E_SUCCESS) {
602                 return false;
603         }
604
605         SPropTagArray = set_SPropTagArray(mt->mem_ctx, 0xA,
606                                           PR_ENTRYID,
607                                           PR_DISPLAY_NAME_UNICODE,
608                                           PR_OBJECT_TYPE,
609                                           PR_DISPLAY_TYPE,
610                                           PR_TRANSMITTABLE_DISPLAY_NAME_UNICODE,
611                                           PR_EMAIL_ADDRESS_UNICODE,
612                                           PR_ADDRTYPE_UNICODE,
613                                           PR_SEND_RICH_INFO,
614                                           PR_7BIT_DISPLAY_NAME_UNICODE,
615                                           PR_SMTP_ADDRESS_UNICODE);
616
617         username = talloc_array(mt->mem_ctx, char *, 2);
618         username[0] = (char *)mt->profile->mailbox;
619         username[1] = NULL;
620
621         retval = ResolveNames(mapi_object_get_session(&obj_message),
622                               (const char **)username, SPropTagArray, 
623                               &RowSet, &flaglist, MAPI_UNICODE);
624         mapitest_print_retval_clean(mt, "ResolveNames", retval);
625         if (retval != MAPI_E_SUCCESS) {
626                 return false;
627         }
628         if (!RowSet) {
629                 mapitest_print(mt, "Null RowSet\n");
630                 return false;
631         }
632         if (!RowSet->cRows) {
633                 mapitest_print(mt, "No values in RowSet\n");
634                 MAPIFreeBuffer(RowSet);
635                 return false;
636         }
637
638         value.ulPropTag = PR_SEND_INTERNET_ENCODING;
639         value.value.l = 0;
640         PropertyRowSet_propcpy(mt->mem_ctx, RowSet, value);
641
642         SRowSet = talloc_zero(RowSet, struct SRowSet);
643         cast_PropertyRowSet_to_SRowSet(SRowSet, RowSet, SRowSet);
644
645         retval = SetRecipientType(&(SRowSet->aRow[0]), MAPI_TO);
646         mapitest_print_retval_clean(mt, "SetRecipientType", retval);
647         if (retval != MAPI_E_SUCCESS) {
648                 MAPIFreeBuffer(RowSet);
649                 MAPIFreeBuffer(flaglist);
650                 return false;
651         }
652         retval = ModifyRecipients(&obj_message, SRowSet);
653         mapitest_print_retval_fmt(mt, "ModifyRecipients", "(%s)", "MAPI_TO");
654         if (retval != MAPI_E_SUCCESS) {
655                 MAPIFreeBuffer(RowSet);
656                 MAPIFreeBuffer(flaglist);
657                 return false;
658         }
659
660         SetRecipientType(&(SRowSet->aRow[0]), MAPI_CC);
661         mapitest_print_retval(mt, "SetRecipientType");
662         retval = ModifyRecipients(&obj_message, SRowSet);
663         mapitest_print_retval_fmt(mt, "ModifyRecipients", "(%s)", "MAPI_CC");
664         if (retval != MAPI_E_SUCCESS) {
665                 MAPIFreeBuffer(RowSet);
666                 MAPIFreeBuffer(flaglist);
667                 return false;
668         }
669
670         SetRecipientType(&(SRowSet->aRow[0]), MAPI_BCC);
671         mapitest_print_retval(mt, "SetRecipientType");
672         retval = ModifyRecipients(&obj_message, SRowSet);
673         mapitest_print_retval_fmt(mt, "ModifyRecipients", "(%s)", "MAPI_BCC");
674         if (retval != MAPI_E_SUCCESS) {
675                 MAPIFreeBuffer(RowSet);
676                 MAPIFreeBuffer(flaglist);
677                 return false;
678         }
679
680         /* Step 4. Save the message */
681         retval = SaveChangesMessage(&obj_folder, &obj_message, KeepOpenReadOnly);
682         mapitest_print_retval(mt, "SaveChangesMessage");
683         if (retval != MAPI_E_SUCCESS) {
684                 MAPIFreeBuffer(RowSet);
685                 MAPIFreeBuffer(flaglist);
686                 return false;
687         }
688
689         /* Step 5. Read recipients */
690         RecipientRows = talloc_zero(mt->mem_ctx, struct ReadRecipientRow);
691         retval = ReadRecipients(&obj_message, 0, &count, &RecipientRows);
692         mapitest_print_retval(mt, "ReadRecipients");
693         MAPIFreeBuffer(RecipientRows);
694         if (retval != MAPI_E_SUCCESS) {
695                 MAPIFreeBuffer(RowSet);
696                 MAPIFreeBuffer(flaglist);
697                 return false;
698         }
699
700         /* Step 6. Delete the message */
701         errno = 0;
702         id_msgs[0] = mapi_object_get_id(&obj_message);
703         retval = DeleteMessage(&obj_folder, id_msgs, 1);
704         mapitest_print_retval(mt, "DeleteMessage");
705         if (retval != MAPI_E_SUCCESS) {
706                 MAPIFreeBuffer(RowSet);
707                 MAPIFreeBuffer(flaglist);
708                 return false;
709         }
710
711         /* Release */
712         MAPIFreeBuffer(RowSet);
713         MAPIFreeBuffer(flaglist);
714         mapi_object_release(&obj_message);
715         mapi_object_release(&obj_folder);
716         mapi_object_release(&obj_store);
717
718         return true;
719 }
720
721
722 /**
723    \details Test the SaveChangesMessage (0xc) operation
724
725    This function:
726    -# Log on the user private mailbox
727    -# Open the Outbox folder
728    -# Create the message
729    -# Save the message
730    -# Delete the message
731
732    \param mt pointer on the top-level mapitest structure
733
734    \return true on success, otherwise false
735  */
736 _PUBLIC_ bool mapitest_oxcmsg_SaveChangesMessage(struct mapitest *mt)
737 {
738         mapi_object_t           obj_store;
739         mapi_object_t           obj_folder;
740         mapi_object_t           obj_message;
741         mapi_id_t               id_folder;
742         mapi_id_t               id_msgs[1];
743
744         /* Step 1. Logon */
745         mapi_object_init(&obj_store);
746         OpenMsgStore(mt->session, &obj_store);
747         mapitest_print_retval(mt, "OpenMsgStore");
748         if (GetLastError() != MAPI_E_SUCCESS) {
749                 return false;
750         }
751
752         /* Step 2. Open Outbox folder */
753         GetDefaultFolder(&obj_store, &id_folder, olFolderOutbox);
754         mapitest_print_retval(mt, "GetDefaultFolder");
755         if (GetLastError() != MAPI_E_SUCCESS) {
756                 return false;
757         }
758
759         mapi_object_init(&obj_folder);
760         OpenFolder(&obj_store, id_folder, &obj_folder);
761         mapitest_print_retval(mt, "OpenFolder");
762         if (GetLastError() != MAPI_E_SUCCESS) {
763                 return false;
764         }
765
766         /* Step 3. Create the message */
767         mapi_object_init(&obj_message);
768         CreateMessage(&obj_folder, &obj_message);
769         mapitest_print_retval(mt, "CreateMessage");
770         if (GetLastError() != MAPI_E_SUCCESS) {
771                 return false;
772         }
773
774         /* Step 4. Save the message */
775         SaveChangesMessage(&obj_folder, &obj_message, KeepOpenReadOnly);
776         mapitest_print_retval(mt, "SaveChangesMessage");
777         if (GetLastError() != MAPI_E_SUCCESS) {
778                 return false;
779         }
780
781         /* Step 5. Delete the saved message */
782         id_msgs[0] = mapi_object_get_id(&obj_message);
783         DeleteMessage(&obj_folder, id_msgs, 1);
784         mapitest_print_retval(mt, "DeleteMessage");
785         if (GetLastError() != MAPI_E_SUCCESS) {
786                 return false;
787         }
788
789         /* Release */
790         mapi_object_release(&obj_message);
791         mapi_object_release(&obj_folder);
792         mapi_object_release(&obj_store);
793
794         return true;
795 }
796
797
798 /**
799    \details Test the GetMessageStatus (0x1f) operation
800
801    This function:
802    -# Log on the user private mailbox
803    -# Open the outbox folder
804    -# Create the message
805    -# Save the message
806    -# Get outbox contents table
807    -# Get messages status
808    -# Delete the message
809
810    \param mt pointer on the top-level mapitest structure
811
812    \return true on success, otherwise false
813  */
814 _PUBLIC_ bool mapitest_oxcmsg_GetMessageStatus(struct mapitest *mt)
815 {
816         enum MAPISTATUS         retval;
817         mapi_object_t           obj_store;
818         mapi_object_t           obj_folder;
819         mapi_object_t           obj_message;
820         mapi_object_t           obj_ctable;
821         mapi_id_t               id_folder;
822         mapi_id_t               id_msgs[1];
823         struct SPropTagArray    *SPropTagArray;
824         struct SRowSet          SRowSet;
825         uint32_t                count;
826         uint32_t                status;
827         uint32_t                i;
828
829         /* Step 1. Logon */
830         mapi_object_init(&obj_store);
831         mapi_object_init(&obj_folder);
832         mapi_object_init(&obj_message);
833         mapi_object_init(&obj_ctable);
834         retval = OpenMsgStore(mt->session, &obj_store);
835         mapitest_print_retval_clean(mt, "OpenMsgStore", retval);
836         if (retval != MAPI_E_SUCCESS) {
837                 return false;
838         }
839
840         /* Step 2. Open Outbox folder */
841         retval = GetDefaultFolder(&obj_store, &id_folder, olFolderOutbox);
842         mapitest_print_retval_clean(mt, "GetDefaultFolder", retval);
843         if (retval != MAPI_E_SUCCESS) {
844                 return false;
845         }
846
847         retval = OpenFolder(&obj_store, id_folder, &obj_folder);
848         mapitest_print_retval_clean(mt, "OpenFolder", retval);
849         if (retval != MAPI_E_SUCCESS) {
850                 return false;
851         }
852
853         /* Step 3. Create the message */
854         retval = CreateMessage(&obj_folder, &obj_message);
855         mapitest_print_retval_clean(mt, "CreateMessage", retval);
856         if (retval != MAPI_E_SUCCESS) {
857                 return false;
858         }
859
860         /* Step 4. Save the message */
861         retval = SaveChangesMessage(&obj_folder, &obj_message, KeepOpenReadOnly);
862         mapitest_print_retval_clean(mt, "SaveChangesMessage", retval);
863         if (retval != MAPI_E_SUCCESS) {
864                 return false;
865         }
866
867         /* Step 5. Get outbox contents table */
868         retval = GetContentsTable(&obj_folder, &obj_ctable, 0, &count);
869         mapitest_print_retval_clean(mt, "GetContentsTable", retval);
870         if (retval != MAPI_E_SUCCESS) {
871                 return false;
872         }
873
874         SPropTagArray = set_SPropTagArray(mt->mem_ctx, 0x2,
875                                           PR_MID, PR_MSG_STATUS);
876         retval = SetColumns(&obj_ctable, SPropTagArray);
877         MAPIFreeBuffer(SPropTagArray);
878         mapitest_print_retval_clean(mt, "GetMessageStatus", retval);
879         if (retval != MAPI_E_SUCCESS) {
880                 return false;
881         }
882
883         /* Step 6. Get Message Status */
884         while (((retval = QueryRows(&obj_ctable, count, TBL_ADVANCE, &SRowSet)) != MAPI_E_NOT_FOUND) &&
885                SRowSet.cRows) {
886                 count -= SRowSet.cRows;
887                 for (i = 0; i < SRowSet.cRows; i++) {
888                         retval = GetMessageStatus(&obj_folder, SRowSet.aRow[i].lpProps[0].value.d, &status);
889                         mapitest_print_retval_clean(mt, "GetMessageStatus", retval);
890                         if (retval != MAPI_E_SUCCESS) {
891                                 return false;
892                         }
893                 }
894         }
895
896         /* Step 7. Delete the saved message */
897         id_msgs[0] = mapi_object_get_id(&obj_message);
898         retval = DeleteMessage(&obj_folder, id_msgs, 1);
899         mapitest_print_retval_clean(mt, "DeleteMessage", retval);
900         if (retval != MAPI_E_SUCCESS) {
901                 return false;
902         }
903
904         /* Release */
905         mapi_object_release(&obj_ctable);
906         mapi_object_release(&obj_message);
907         mapi_object_release(&obj_folder);
908         mapi_object_release(&obj_store);
909
910         return true;
911 }
912
913
914 struct msgstatus {
915         uint32_t        status;
916         const char      *name;
917 };
918
919 static struct msgstatus msgstatus[] = {
920         {MSGSTATUS_HIDDEN,              "MSGSTATUS_HIDDEN"},
921         {MSGSTATUS_HIGHLIGHTED,         "MSGSTATUS_HIGHLIGHTED"},
922         {MSGSTATUS_TAGGED,              "MSGSTATUS_TAGGED"},
923         {MSGSTATUS_REMOTE_DOWNLOAD,     "MSGSTATUS_REMOTE_DOWNLOAD"},
924         {MSGSTATUS_REMOTE_DELETE,       "MSGSTATUS_REMOTE_DELETE"},
925         {MSGSTATUS_DELMARKED,           "MSGSTATUS_DELMARKED"},
926         {0,                             NULL}
927 };
928
929 /**
930    \details Test the GetMessageStatus (0x1f) operation
931
932    This function:
933    -# Log on the user private mailbox
934    -# Open the outbox folder
935    -# Create the message
936    -# Save the message
937    -# Get outbox contents table
938    -# Set different messages status, then get them and compare values
939    -# Delete the message
940
941    \param mt pointer on the top-level mapitest structure
942
943    \return true on success, otherwise false
944  */
945 _PUBLIC_ bool mapitest_oxcmsg_SetMessageStatus(struct mapitest *mt)
946 {
947         enum MAPISTATUS         retval;
948         mapi_object_t           obj_store;
949         mapi_object_t           obj_folder;
950         mapi_object_t           obj_message;
951         mapi_object_t           obj_ctable;
952         mapi_id_t               id_folder;
953         mapi_id_t               id_msgs[1];
954         struct SPropTagArray    *SPropTagArray;
955         struct SRowSet          SRowSet;
956         uint32_t                count;
957         uint32_t                i;
958         uint32_t                ulOldStatus = 0;
959         uint32_t                ulOldStatus2 = 0;
960         bool                    ret = true;
961
962         /* Step 1. Logon */
963         mapi_object_init(&obj_store);
964         mapi_object_init(&obj_folder);
965         mapi_object_init(&obj_message);
966         mapi_object_init(&obj_ctable);
967         retval = OpenMsgStore(mt->session, &obj_store);
968         mapitest_print_retval_clean(mt, "OpenMsgStore", retval);
969         if (retval != MAPI_E_SUCCESS) {
970                 ret = false;
971                 goto release;
972         }
973
974         /* Step 2. Open Outbox folder */
975         retval = GetDefaultFolder(&obj_store, &id_folder, olFolderOutbox);
976         mapitest_print_retval_clean(mt, "GetDefaultFolder", retval);
977         if (retval != MAPI_E_SUCCESS) {
978                 ret = false;
979                 goto release;
980         }
981
982         retval = OpenFolder(&obj_store, id_folder, &obj_folder);
983         mapitest_print_retval_clean(mt, "OpenFolder", retval);
984         if (retval != MAPI_E_SUCCESS) {
985                 ret = false;
986                 goto release;
987         }
988
989         /* Step 3. Create the message */
990         retval = CreateMessage(&obj_folder, &obj_message);
991         mapitest_print_retval_clean(mt, "CreateMessage", retval);
992         if (retval != MAPI_E_SUCCESS) {
993                 ret = false;
994                 goto release;
995         }
996
997         /* Step 4. Save the message */
998         retval = SaveChangesMessage(&obj_folder, &obj_message, KeepOpenReadOnly);
999         mapitest_print_retval_clean(mt, "SaveChangesMessage", retval);
1000         if (retval != MAPI_E_SUCCESS) {
1001                 ret = false;
1002                 goto release;
1003         }
1004
1005         /* Step 5. Get outbox contents table */
1006         retval = GetContentsTable(&obj_folder, &obj_ctable, 0, &count);
1007         mapitest_print_retval_clean(mt, "GetContentsTable", retval);
1008         if (retval != MAPI_E_SUCCESS) {
1009                 ret = false;
1010                 goto release;
1011         }
1012
1013         SPropTagArray = set_SPropTagArray(mt->mem_ctx, 0x2,
1014                                           PR_MID, PR_MSG_STATUS);
1015         retval = SetColumns(&obj_ctable, SPropTagArray);
1016         mapitest_print_retval_clean(mt, "SetColumns", retval);
1017         MAPIFreeBuffer(SPropTagArray);
1018         if (retval != MAPI_E_SUCCESS) {
1019                 ret = false;
1020                 goto release;
1021         }
1022
1023         /* Fetch the first email */
1024         retval = QueryRows(&obj_ctable, 1, TBL_NOADVANCE, &SRowSet);
1025         mapitest_print_retval_clean(mt, "QueryRows", retval);
1026         if (retval != MAPI_E_SUCCESS || SRowSet.cRows == 0) {
1027                 ret = false;
1028                 goto release;
1029         }
1030
1031         /* Step 6. SetMessageStatus + GetMessageStatus + Comparison */
1032         for (i = 0; msgstatus[i].name; i++) {
1033                 retval = SetMessageStatus(&obj_folder, SRowSet.aRow[0].lpProps[0].value.d,
1034                                           msgstatus[i].status, msgstatus[i].status, &ulOldStatus2);
1035                 mapitest_print_retval_clean(mt, "SetMessageStatus", retval);
1036                 if (retval != MAPI_E_SUCCESS) {
1037                         ret = false;
1038                         goto release;
1039                 }
1040
1041                 retval = GetMessageStatus(&obj_folder, SRowSet.aRow[0].lpProps[0].value.d, &ulOldStatus);
1042                 mapitest_print_retval_clean(mt, "GetMessageStatus", retval);
1043                 if (retval != MAPI_E_SUCCESS) {
1044                         ret = false;
1045                         goto release;
1046                 }
1047
1048                 if ((ulOldStatus != ulOldStatus2) && (ulOldStatus & msgstatus[i].status)) {
1049                         errno = 0;
1050                         mapitest_print(mt, "* %-35s: %s 0x%.8x\n", "Comparison", msgstatus[i].name, GetLastError());
1051                 }
1052         }
1053
1054         /* Step 7. Delete the saved message */
1055         id_msgs[0] = mapi_object_get_id(&obj_message);
1056         DeleteMessage(&obj_folder, id_msgs, 1);
1057         mapitest_print_retval(mt, "DeleteMessage");
1058         if (GetLastError() != MAPI_E_SUCCESS) {
1059                 return false;
1060         }
1061
1062 release:
1063         /* Release */
1064         mapi_object_release(&obj_ctable);
1065         mapi_object_release(&obj_message);
1066         mapi_object_release(&obj_folder);
1067         mapi_object_release(&obj_store);
1068
1069         return ret;
1070 }
1071
1072 /**
1073    \details Test the SetReadFlags (0x66) operation
1074
1075    This function:
1076    -# Opens the Inbox folder and creates some test content
1077    -# Checks that the PR_MESSAGE_FLAGS property on each message is 0x0
1078    -# Apply SetReadFlags() on every second messages
1079    -# Check the results are as expected
1080    -# Apply SetReadFlags() again
1081    -# Check the results are as expected
1082    -# Cleanup
1083         
1084    \param mt pointer on the top-level mapitest structure
1085
1086    \return true on success, otherwise false
1087  */
1088 _PUBLIC_ bool mapitest_oxcmsg_SetReadFlags(struct mapitest *mt)
1089 {
1090         enum MAPISTATUS         retval;
1091         bool                    ret = true;
1092         mapi_object_t           obj_htable;
1093         mapi_object_t           obj_test_folder;
1094         struct SPropTagArray    *SPropTagArray;
1095         struct SRowSet          SRowSet;
1096         struct mt_common_tf_ctx *context;
1097         int                     i;
1098         uint64_t                messageIds[5];
1099
1100         /* Step 1. Logon */
1101         if (! mapitest_common_setup(mt, &obj_htable, NULL)) {
1102                 return false;
1103         }
1104
1105         /* Fetch the contents table for the test folder */
1106         context = mt->priv;
1107         mapi_object_init(&(obj_test_folder));
1108         retval = GetContentsTable(&(context->obj_test_folder), &(obj_test_folder), 0, NULL);
1109         mapitest_print_retval_clean(mt, "GetContentsTable", retval);
1110         if (retval != MAPI_E_SUCCESS) {
1111                 ret = false;
1112                 goto cleanup;
1113         }
1114
1115         SPropTagArray = set_SPropTagArray(mt->mem_ctx, 0x2, PR_MID, PR_MESSAGE_FLAGS);
1116         retval = SetColumns(&obj_test_folder, SPropTagArray);
1117         mapitest_print_retval_clean(mt, "SetColumns", retval);
1118         MAPIFreeBuffer(SPropTagArray);
1119         if (retval != MAPI_E_SUCCESS) {
1120                 ret = false;
1121                 goto cleanup;
1122         }
1123
1124         retval = QueryRows(&obj_test_folder, 10, TBL_NOADVANCE, &SRowSet);
1125         mapitest_print_retval_clean(mt, "QueryRows", retval);
1126         if (retval != MAPI_E_SUCCESS) {
1127                 ret = false;
1128                 goto cleanup;
1129         }
1130         /* 0x0400 is mfEverRead - the message has been read at least once. We see this on Exchange 2010 */
1131         for (i = 0; i < 10; ++i) {
1132                 if ((*(const uint32_t *)get_SPropValue_data(&(SRowSet.aRow[i].lpProps[1])) & ~0x0400) != 0x0) {
1133                         mapitest_print(mt, "* %-35s: unexpected flag at %i 0x%x\n", "QueryRows", i,
1134                                        (*(const uint32_t *)get_SPropValue_data(&(SRowSet.aRow[i].lpProps[1]))));
1135                         ret = false;
1136                         goto cleanup;
1137                 }
1138         }       
1139
1140         for (i = 0; i < 5; ++i) {
1141                 messageIds[i] = (*(const uint64_t *)get_SPropValue_data(&(SRowSet.aRow[i*2].lpProps[0])));
1142         }
1143
1144         retval = SetReadFlags(&(context->obj_test_folder), 0x0, 5, messageIds);
1145         mapitest_print_retval_clean(mt, "SetReadFlags", retval);
1146         if (retval != MAPI_E_SUCCESS) {
1147                 ret = false;
1148                 goto cleanup;
1149         }
1150
1151         retval = QueryRows(&obj_test_folder, 10, TBL_NOADVANCE, &SRowSet);
1152         mapitest_print_retval_clean(mt, "QueryRows", retval);
1153         if (retval != MAPI_E_SUCCESS) {
1154                 ret = false;
1155                 goto cleanup;
1156         }
1157         for (i = 0; i < 10; i+=2) {
1158                 if ((*(const uint32_t *)get_SPropValue_data(&(SRowSet.aRow[i].lpProps[1])) & ~0x0400) != MSGFLAG_READ) {
1159                         mapitest_print(mt, "* %-35s: unexpected flag (0) at %i 0x%x\n", "QueryRows", i,
1160                                        (*(const uint32_t *)get_SPropValue_data(&(SRowSet.aRow[i].lpProps[1]))));
1161                         ret = false;
1162                         goto cleanup;
1163                 }
1164                 if ((*(const uint32_t *)get_SPropValue_data(&(SRowSet.aRow[i+1].lpProps[1])) & ~0x0400) != 0x0) {
1165                         mapitest_print(mt, "* %-35s: unexpected flag (1) at %i 0x%x\n", "QueryRows", i,
1166                                        (*(const uint32_t *)get_SPropValue_data(&(SRowSet.aRow[i+1].lpProps[1]))));
1167                         ret = false;
1168                         goto cleanup;
1169                 }
1170         }       
1171
1172         SetReadFlags(&(context->obj_test_folder), CLEAR_READ_FLAG, 5, messageIds);
1173
1174         retval = QueryRows(&obj_test_folder, 10, TBL_NOADVANCE, &SRowSet);
1175         mapitest_print_retval_clean(mt, "QueryRows", retval);
1176         if (retval != MAPI_E_SUCCESS) {
1177                 ret = false;
1178                 goto cleanup;
1179         }
1180         for (i = 0; i < 10; ++i) {
1181                 if ((*(const uint32_t *)get_SPropValue_data(&(SRowSet.aRow[i].lpProps[1])) & ~0x0400) != 0x0) {
1182                         mapitest_print(mt, "* %-35s: unexpected flag (3) at %i 0x%x\n", "QueryRows", i,
1183                                        (*(const uint32_t *)get_SPropValue_data(&(SRowSet.aRow[i].lpProps[1]))));
1184                         ret = false;
1185                         goto cleanup;
1186                 }
1187         }
1188
1189  cleanup:
1190         /* Cleanup and release */
1191         talloc_free(SRowSet.aRow);
1192         mapi_object_release(&obj_htable);
1193         mapitest_common_cleanup(mt);
1194
1195         return ret;
1196 }
1197
1198 /**
1199    \details Test the OpenEmbeddedMessage (0x46) and CreateAttach (0x23) operations
1200
1201    This function:
1202         -# Logs on the user private mailbox
1203         -# Open the Inbox folder         
1204         -# Create a test message          
1205         -# Embed a message in the test message
1206         -# Delete the test message                  
1207
1208    \param mt pointer to the top-level mapitest structure
1209
1210    \return true on success, otherwise false
1211  */                                        
1212 _PUBLIC_ bool mapitest_oxcmsg_OpenEmbeddedMessage(struct mapitest *mt)
1213 {                                                                     
1214         enum MAPISTATUS         retval;                               
1215         bool                    ret;                                  
1216         mapi_object_t           obj_store;                            
1217         mapi_object_t           obj_folder;                           
1218         mapi_object_t           obj_message;
1219         mapi_object_t           obj_attach;
1220         mapi_object_t           obj_embeddedmsg;
1221         mapi_id_t               id_msgs[1];                           
1222         struct SPropValue       attach[2];
1223         struct SRowSet          SRowSet;
1224         struct SPropTagArray    SPropTagArray;
1225
1226         /* Step 1. Logon */
1227         mapi_object_init(&obj_store);
1228         retval = OpenMsgStore(mt->session, &obj_store);
1229         if (retval != MAPI_E_SUCCESS) {
1230                 mapi_object_release(&obj_store);
1231                 return false;                          
1232         }
1233
1234         /* Step 2. Open Inbox folder */
1235         mapi_object_init(&obj_folder);
1236         ret = mapitest_common_folder_open(mt, &obj_store, &obj_folder, olFolderInbox);
1237         if (ret == false) {
1238                 mapi_object_release(&obj_folder);
1239                 mapi_object_release(&obj_store);
1240                 return false;
1241         }
1242
1243         /* Step 3. Create the tmp message and save it */
1244         mapi_object_init(&obj_message);
1245         ret = mapitest_common_message_create(mt, &obj_folder, &obj_message, OXCMSG_SETREADFLAGS);
1246         if (ret == false) return ret;
1247
1248         retval = SaveChangesMessage(&obj_folder, &obj_message, KeepOpenReadWrite);
1249         mapitest_print(mt, "* %-35s: 0x%.8x\n", "SaveChangesMessage", retval);
1250         if (retval != MAPI_E_SUCCESS) {
1251                 mapi_object_release(&obj_message);
1252                 mapi_object_release(&obj_folder);
1253                 mapi_object_release(&obj_store);
1254                 return false;
1255         }
1256
1257         /* Step 4. Embed another message in the message */
1258         mapi_object_init(&obj_attach);
1259         retval = CreateAttach(&obj_message, &obj_attach);
1260         mapitest_print(mt, "* %-35s: 0x%.8x\n", "CreateAttach", retval);
1261         if (retval != MAPI_E_SUCCESS) {
1262                 mapi_object_release(&obj_attach);
1263                 mapi_object_release(&obj_message);
1264                 mapi_object_release(&obj_folder);
1265                 mapi_object_release(&obj_store);
1266                 return false;
1267         }
1268
1269         /* use SetProps() to set the attachment up */
1270         attach[0].ulPropTag = PR_ATTACH_METHOD;
1271         attach[0].value.l = ATTACH_EMBEDDED_MSG;
1272         attach[1].ulPropTag = PR_RENDERING_POSITION;
1273         attach[1].value.l = 0;
1274         retval = SetProps(&obj_attach, 0, attach, 2);
1275         mapitest_print(mt, "* %-35s: 0x%.8x\n", "SetProps", retval);
1276         if (retval != MAPI_E_SUCCESS) {
1277                 mapi_object_release(&obj_attach);
1278                 mapi_object_release(&obj_message);
1279                 mapi_object_release(&obj_folder);
1280                 mapi_object_release(&obj_store);
1281                 return false;
1282         }
1283
1284         mapi_object_init(&obj_embeddedmsg);
1285         retval = OpenEmbeddedMessage(&obj_attach, &obj_embeddedmsg, MAPI_CREATE);
1286         mapitest_print(mt, "* %-35s: 0x%.8x\n", "OpenEmbeddedMessage", retval);
1287         if (retval != MAPI_E_SUCCESS) {
1288                 mapi_object_release(&obj_embeddedmsg);
1289                 mapi_object_release(&obj_attach);
1290                 mapi_object_release(&obj_message);
1291                 mapi_object_release(&obj_folder);
1292                 mapi_object_release(&obj_store);
1293                 return false;
1294         }
1295
1296         ret = mapitest_common_message_fill(mt, &obj_embeddedmsg, "MT EmbeddedMessage");
1297         if (ret == false) {
1298                 mapi_object_release(&obj_embeddedmsg);
1299                 mapi_object_release(&obj_attach);
1300                 mapi_object_release(&obj_message);
1301                 mapi_object_release(&obj_folder);
1302                 mapi_object_release(&obj_store);
1303                 return false;
1304         }
1305
1306         // Save the changes to the embedded message
1307         retval = SaveChangesMessage(&obj_message, &obj_embeddedmsg, KeepOpenReadOnly);
1308         mapitest_print(mt, "* %-35s: 0x%.8x\n", "SaveChangesMessage", retval);
1309         if (retval != MAPI_E_SUCCESS) {
1310                 mapi_object_release(&obj_embeddedmsg);
1311                 mapi_object_release(&obj_attach);
1312                 mapi_object_release(&obj_message);
1313                 mapi_object_release(&obj_folder);
1314                 mapi_object_release(&obj_store);
1315                 return false;
1316         }
1317         // Save the changes to the attachment and then the message
1318         retval = SaveChangesAttachment(&obj_message, &obj_attach, KeepOpenReadOnly);
1319         mapitest_print(mt, "* %-35s: 0x%.8x\n", "SaveChangesAttachment", retval);
1320         if (retval != MAPI_E_SUCCESS) {
1321                 mapi_object_release(&obj_embeddedmsg);
1322                 mapi_object_release(&obj_attach);
1323                 mapi_object_release(&obj_message);
1324                 mapi_object_release(&obj_folder);
1325                 mapi_object_release(&obj_store);
1326                 return false;
1327         }
1328
1329         retval = SaveChangesMessage(&obj_folder, &obj_message, KeepOpenReadOnly);
1330         mapitest_print(mt, "* %-35s: 0x%.8x\n", "SaveChangesMessage", retval);
1331         if (retval != MAPI_E_SUCCESS) {
1332                 mapi_object_release(&obj_embeddedmsg);
1333                 mapi_object_release(&obj_attach);
1334                 mapi_object_release(&obj_message);
1335                 mapi_object_release(&obj_folder);
1336                 mapi_object_release(&obj_store);
1337                 return false;
1338         }
1339
1340         /* Step 5. Open the embedded message */
1341         mapi_object_init(&obj_attach);
1342         retval = OpenAttach(&obj_message, 0, &obj_attach);
1343         mapitest_print(mt, "* %-35s: 0x%.8x\n", "OpenAttach", retval);
1344         if (retval != MAPI_E_SUCCESS) {
1345                 mapi_object_release(&obj_embeddedmsg);
1346                 mapi_object_release(&obj_attach);
1347                 mapi_object_release(&obj_message);
1348                 mapi_object_release(&obj_folder);
1349                 mapi_object_release(&obj_store);
1350                 return false;
1351         }
1352         retval = OpenEmbeddedMessage(&obj_attach, &obj_embeddedmsg, MAPI_READONLY);
1353         mapitest_print(mt, "* %-35s: 0x%.8x\n", "OpenEmbeddedMessage", retval);
1354         if (retval != MAPI_E_SUCCESS) {
1355                 mapi_object_release(&obj_embeddedmsg);
1356                 mapi_object_release(&obj_attach);
1357                 mapi_object_release(&obj_message);
1358                 mapi_object_release(&obj_folder);
1359                 mapi_object_release(&obj_store);
1360                 return false;
1361         }
1362
1363         /* Step 6. Get the recipient table */
1364         retval = GetRecipientTable(&obj_embeddedmsg, &SRowSet, &SPropTagArray);
1365         mapitest_print(mt, "* %-35s: 0x%.8x\n", "GetRecipientTable", retval);
1366
1367         mapitest_print_SRowSet(mt, &SRowSet, "\t * ");
1368         mapi_object_release(&obj_embeddedmsg);
1369
1370         /* Step 7. Delete the message */
1371         id_msgs[0] = mapi_object_get_id(&obj_message);
1372         retval = DeleteMessage(&obj_folder, id_msgs, 1);
1373         mapitest_print(mt, "* %-35s: 0x%.8x\n", "DeleteMessage", GetLastError());
1374         if (GetLastError() != MAPI_E_SUCCESS) {
1375                 mapi_object_release(&obj_attach);
1376                 mapi_object_release(&obj_message);
1377                 mapi_object_release(&obj_folder);
1378                 mapi_object_release(&obj_store);
1379                 return false;
1380         }
1381
1382         /* Release */
1383         mapi_object_release(&obj_attach);
1384         mapi_object_release(&obj_message);
1385         mapi_object_release(&obj_folder);
1386         mapi_object_release(&obj_store);
1387
1388         return true;
1389 }
1390
1391
1392 /**
1393    \details Test the GetValidAttachments (0x52) and CreateAttach (0x23) operations
1394
1395    This function:
1396         -# Logs on the user private mailbox
1397         -# Open the Inbox folder         
1398         -# Create a test message          
1399         -# Check the number of valid attachments is zero
1400         -# Create two attachments
1401         -# Check the number of valid attachments is two (numbered 0 and 1)
1402         -# Delete the first attachment
1403         -# Check the number of valid attachments is one (numbered 1)
1404         -# Delete the test message                  
1405
1406    \param mt pointer to the top-level mapitest structure
1407
1408    \return true on success, otherwise false
1409  */                                        
1410 _PUBLIC_ bool mapitest_oxcmsg_GetValidAttachments(struct mapitest *mt)
1411 {                                                                     
1412         enum MAPISTATUS         retval;                               
1413         bool                    ret;                                  
1414         mapi_object_t           obj_store;                            
1415         mapi_object_t           obj_folder;                           
1416         mapi_object_t           obj_message;
1417         mapi_object_t           obj_attach0;
1418         mapi_object_t           obj_attach1;
1419         mapi_id_t               id_msgs[1];                           
1420         struct SPropValue       attach[3];
1421         uint16_t                numAttach;
1422         uint32_t                *attachmentIds;
1423
1424         /* Step 1. Logon */
1425         mapi_object_init(&obj_store);
1426         retval = OpenMsgStore(mt->session, &obj_store);
1427         if (retval != MAPI_E_SUCCESS) {
1428                 mapi_object_release(&obj_store);
1429                 return false;                          
1430         }
1431
1432         /* Step 2. Open Inbox folder */
1433         mapi_object_init(&obj_folder);
1434         ret = mapitest_common_folder_open(mt, &obj_store, &obj_folder, olFolderInbox);
1435         if (ret == false) {
1436                 mapi_object_release(&obj_folder);
1437                 mapi_object_release(&obj_store);
1438                 return false;
1439         }
1440
1441         /* Step 3. Create the test message and save it */
1442         mapi_object_init(&obj_message);
1443         ret = mapitest_common_message_create(mt, &obj_folder, &obj_message, OXCMSG_SETREADFLAGS);
1444         if (ret == false) return ret;
1445
1446         retval = SaveChangesMessage(&obj_folder, &obj_message, KeepOpenReadWrite);
1447         mapitest_print_retval_clean(mt, "SaveChangesMessage", retval);
1448         if (retval != MAPI_E_SUCCESS) {
1449                 mapi_object_release(&obj_message);
1450                 mapi_object_release(&obj_folder);
1451                 mapi_object_release(&obj_store);
1452                 return false;
1453         }
1454
1455         ret = true;
1456
1457         /* Step 4. Check the number of valid attachments */
1458         numAttach = 99;
1459         retval = GetValidAttach(&obj_message, &numAttach, &attachmentIds);
1460         mapitest_print_retval_fmt_clean(mt, "GetValidAttach", retval, "%i", numAttach);
1461         if (numAttach != 0) {
1462                 ret = false;
1463                 goto cleanup_wo_attach;
1464         }
1465         if (retval != MAPI_E_SUCCESS) {
1466                 ret = false;
1467                 goto cleanup_wo_attach;
1468         }
1469
1470         /* Step 5. Create two attachments to the message */
1471         mapi_object_init(&obj_attach0);
1472         mapi_object_init(&obj_attach1);
1473         retval = CreateAttach(&obj_message, &obj_attach0);
1474         mapitest_print_retval_clean(mt, "CreateAttach", retval);
1475         if (retval != MAPI_E_SUCCESS) {
1476                 ret = false;
1477                 goto cleanup;
1478         }
1479
1480         /* use SetProps() to set the attachment up */
1481         attach[0].ulPropTag = PR_ATTACH_METHOD;
1482         attach[0].value.l = ATTACH_BY_VALUE;
1483         attach[1].ulPropTag = PR_RENDERING_POSITION;
1484         attach[1].value.l = 0;
1485         attach[2].ulPropTag = PR_ATTACH_FILENAME;
1486         attach[2].value.lpszA = "Attachment 0";
1487         retval = SetProps(&obj_attach0, 0, attach, 3);
1488         mapitest_print_retval_clean(mt, "SetProps", retval);
1489         if (retval != MAPI_E_SUCCESS) {
1490                 ret = false;
1491                 goto cleanup;
1492         }
1493
1494         /* Save the changes to the attachment and then the message */
1495         retval = SaveChangesAttachment(&obj_message, &obj_attach0, KeepOpenReadOnly);
1496         mapitest_print_retval_clean(mt, "SaveChangesAttachment", retval);
1497         if (retval != MAPI_E_SUCCESS) {
1498                 ret = false;
1499                 goto cleanup;
1500         }
1501
1502         retval = CreateAttach(&obj_message, &obj_attach1);
1503         mapitest_print_retval_clean(mt, "CreateAttach", retval);
1504         if (retval != MAPI_E_SUCCESS) {
1505                 ret = false;
1506                 goto cleanup;
1507         }
1508
1509         /* use SetProps() to set the attachment up */
1510         attach[0].ulPropTag = PR_ATTACH_METHOD;
1511         attach[0].value.l = ATTACH_BY_VALUE;
1512         attach[1].ulPropTag = PR_RENDERING_POSITION;
1513         attach[1].value.l = 0;
1514         attach[2].ulPropTag = PR_ATTACH_FILENAME;
1515         attach[2].value.lpszA = "Attachment 1";
1516         retval = SetProps(&obj_attach1, 0, attach, 3);
1517         mapitest_print_retval_clean(mt, "SetProps", retval);
1518         if (retval != MAPI_E_SUCCESS) {
1519                 ret = false;
1520                 goto cleanup;
1521         }
1522
1523         /* Save the changes to the attachment and then the message */
1524         retval = SaveChangesAttachment(&obj_message, &obj_attach1, KeepOpenReadOnly);
1525         mapitest_print_retval_clean(mt, "SaveChangesAttachment", retval);
1526         if (retval != MAPI_E_SUCCESS) {
1527                 ret = false;
1528                 goto cleanup;
1529         }
1530
1531         retval = SaveChangesMessage(&obj_folder, &obj_message, KeepOpenReadWrite);
1532         mapitest_print_retval_clean(mt, "SaveChangesMessage", retval);
1533         if (retval != MAPI_E_SUCCESS) {
1534                 ret = false;
1535                 goto cleanup;
1536         }
1537
1538         /* Step 6. Check the number of valid attachments */
1539         numAttach = 99;
1540         retval = GetValidAttach(&obj_message, &numAttach, &attachmentIds);
1541         mapitest_print_retval_fmt_clean(mt, "GetValidAttach", retval, "%i", numAttach);
1542         if (numAttach != 2) {
1543                 ret = false;
1544                 goto cleanup;
1545         }
1546         mapitest_print(mt, "IDs: %d, %d\n", attachmentIds[0], attachmentIds[1]);
1547         if ( (attachmentIds[0] != 0) || (attachmentIds[1] != 1) ) {
1548                 ret = false;
1549                 goto cleanup;
1550         }
1551         if (retval != MAPI_E_SUCCESS) {
1552                 ret = false;
1553                 goto cleanup;
1554         }
1555
1556         /* Step 7. Delete the first attachment */
1557         retval = DeleteAttach(&obj_message, attachmentIds[0]);
1558         mapitest_print_retval_clean(mt, "DeleteAttach", retval);
1559         if (retval != MAPI_E_SUCCESS) {
1560                 ret = false;
1561                 goto cleanup;
1562         }
1563
1564         /* Step 8. Check the number of valid attachments */
1565         numAttach = 99;
1566         retval = GetValidAttach(&obj_message, &numAttach, &attachmentIds);
1567         mapitest_print_retval_fmt_clean(mt, "GetValidAttach", retval, "%i", numAttach);
1568         if (numAttach != 1) {
1569                 ret = false;
1570                 goto cleanup;
1571         }
1572         mapitest_print(mt, "IDs: %d\n", attachmentIds[0]);
1573         if ( (attachmentIds[0] != 1) ) {
1574                 ret = false;
1575                 goto cleanup;
1576         }
1577         if (retval != MAPI_E_SUCCESS) {
1578                 ret = false;
1579                 goto cleanup;
1580         }
1581
1582         /* Step 9. Delete the message */
1583         id_msgs[0] = mapi_object_get_id(&obj_message);
1584         retval = DeleteMessage(&obj_folder, id_msgs, 1);
1585         mapitest_print_retval_clean(mt, "DeleteMessage", retval);
1586         if (retval != MAPI_E_SUCCESS) {
1587                 ret = false;
1588                 goto cleanup;
1589         }
1590
1591 cleanup:
1592         /* Release */
1593         mapi_object_release(&obj_attach0);
1594         mapi_object_release(&obj_attach1);
1595 cleanup_wo_attach:
1596         mapi_object_release(&obj_message);
1597         mapi_object_release(&obj_folder);
1598         mapi_object_release(&obj_store);
1599
1600         return ret;
1601 }
1602
1603 /**
1604    \details Test the ReloadCachedInformation (0x10) operation
1605
1606    This function:
1607    -# Logs on to the user private mailbox
1608    -# Open the outbox folder
1609    -# Create the message
1610    -# Save the message
1611    -# Reloads the cached message information
1612    -# Delete the message
1613
1614    \param mt pointer to the top-level mapitest structure
1615
1616    \return true on success, otherwise false
1617  */
1618 _PUBLIC_ bool mapitest_oxcmsg_ReloadCachedInformation(struct mapitest *mt)
1619 {
1620         enum MAPISTATUS         retval;
1621         mapi_object_t           obj_store;
1622         mapi_object_t           obj_folder;
1623         mapi_object_t           obj_message;
1624         mapi_id_t               id_folder;
1625         mapi_id_t               id_msgs[1];
1626         bool                    ret;
1627
1628         ret = true;
1629
1630         mapi_object_init(&obj_folder);
1631         mapi_object_init(&obj_message);
1632         /* Step 1. Logon */
1633         mapi_object_init(&obj_store);
1634         retval = OpenMsgStore(mt->session, &obj_store);
1635         mapitest_print_retval(mt, "OpenMsgStore");
1636         if (retval != MAPI_E_SUCCESS) {
1637                 ret = false;
1638                 goto cleanup;
1639         }
1640
1641         /* Step 2. Open Outbox folder */
1642         retval = GetDefaultFolder(&obj_store, &id_folder, olFolderOutbox);
1643         mapitest_print_retval(mt, "GetDefaultFolder");
1644         if (retval != MAPI_E_SUCCESS) {
1645                 ret = false;
1646                 goto cleanup;
1647         }
1648
1649         retval = OpenFolder(&obj_store, id_folder, &obj_folder);
1650         mapitest_print_retval(mt, "OpenFolder");
1651         if (retval != MAPI_E_SUCCESS) {
1652                 ret = false;
1653                 goto cleanup;
1654         }
1655
1656         /* Step 3. Create the message */
1657         retval = CreateMessage(&obj_folder, &obj_message);
1658         mapitest_print_retval(mt, "CreateMessage");
1659         if (retval != MAPI_E_SUCCESS) {
1660                 ret = false;
1661                 goto cleanup;
1662         }
1663
1664         /* Step 4. Save the message */
1665         retval = SaveChangesMessage(&obj_folder, &obj_message, KeepOpenReadOnly);
1666         mapitest_print_retval(mt, "SaveChangesMessage");
1667         if (retval != MAPI_E_SUCCESS) {
1668                 ret = false;
1669                 goto cleanup;
1670         }
1671
1672         /* Step 5. Reload cached information */
1673         retval = ReloadCachedInformation(&obj_message);
1674         mapitest_print_retval(mt, "ReloadCachedInformation");
1675         if (retval != MAPI_E_SUCCESS) {
1676                 ret = false;
1677                 goto cleanup;
1678         }
1679
1680         /* Step 6. Delete the saved message */
1681         id_msgs[0] = mapi_object_get_id(&obj_message);
1682         retval = DeleteMessage(&obj_folder, id_msgs, 1);
1683         mapitest_print_retval(mt, "DeleteMessage");
1684         if (retval != MAPI_E_SUCCESS) {
1685                 ret = false;
1686                 goto cleanup;
1687         }
1688
1689 cleanup:
1690         /* Release */
1691         mapi_object_release(&obj_message);
1692         mapi_object_release(&obj_folder);
1693         mapi_object_release(&obj_store);
1694
1695         return ret;
1696 }