server: intialize aux_header buffer to null if the data is missing.
[tridge/openchange.git] / branches / plugfest / utils / mapitest / modules / module_oxcprpt.c
1 /*
2    Stand-alone MAPI testsuite
3
4    OpenChange Project - PROPERTY AND STREAM OBJECT PROTOCOL operations
5
6    Copyright (C) Julien Kerihuel 2008
7    Copyright (C) Brad Hards 2008-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_oxcprpt.c
28
29    \brief Property and Stream Object Protocol test suite
30 */
31
32 /**
33    \details Test the GetProps (0x7) operation
34
35    This function:
36    -# Log on the user private mailbox
37    -# Retrieve the properties list using GetPropList
38    -# Retrieve their associated values using the GetProps operation
39
40    \param mt pointer on the top-level mapitest structure
41
42    \return true on success, otherwise false
43  */
44 _PUBLIC_ bool mapitest_oxcprpt_GetProps(struct mapitest *mt)
45 {
46         enum MAPISTATUS         retval;
47         mapi_object_t           obj_store;
48         struct SPropTagArray    *SPropTagArray;
49         struct SPropValue       *lpProps;
50         uint32_t                cValues;
51
52         /* Step 1. Logon Private Mailbox */
53         mapi_object_init(&obj_store);
54         retval = OpenMsgStore(mt->session, &obj_store);
55         mapitest_print_retval(mt, "OpenMsgStore");
56         if (retval != MAPI_E_SUCCESS) {
57                 return false;
58         }       
59         
60         /* Step 2. Retrieve the properties list using GetPropList */
61         SPropTagArray = talloc_zero(mt->mem_ctx, struct SPropTagArray);
62         retval = GetPropList(&obj_store, SPropTagArray);
63         mapitest_print_retval(mt, "GetPropList");
64         if (retval != MAPI_E_SUCCESS) {
65                 MAPIFreeBuffer(SPropTagArray);
66                 return false;
67         }
68
69         /* Step 3. Call the GetProps operation */
70         retval = GetProps(&obj_store, SPropTagArray, &lpProps, &cValues);
71         mapitest_print_retval(mt, "GetProps");
72         if (retval != MAPI_E_SUCCESS) {
73                 MAPIFreeBuffer(SPropTagArray);
74                 return false;
75         }
76         MAPIFreeBuffer(SPropTagArray);
77
78         /* Release */
79         mapi_object_release(&obj_store);
80
81         return true;
82 }
83
84
85 /**
86    \details Test the GetPropsAll (0x8) operation
87
88    This function:
89    -# Log on the user private mailbox
90    -# Retrieve the whole set of properties and values associated to the store object
91
92    \param mt pointer on the top-level mapitest structure
93
94    \return true on success, otherwise false
95  */
96 _PUBLIC_ bool mapitest_oxcprpt_GetPropsAll(struct mapitest *mt)
97 {
98         enum MAPISTATUS                 retval;
99         mapi_object_t                   obj_store;
100         struct mapi_SPropValue_array    properties_array;
101
102         /* Step 1. Logon Private Mailbox */
103         mapi_object_init(&obj_store);
104         retval = OpenMsgStore(mt->session, &obj_store);
105         mapitest_print_retval(mt, "OpenMsgStore");
106         if (retval != MAPI_E_SUCCESS) {
107                 return false;
108         }
109
110         /* Step 2. GetPropsAll operation */
111         retval = GetPropsAll(&obj_store, &properties_array);
112         mapitest_print_retval(mt, "GetPropsAll");
113         if (retval != MAPI_E_SUCCESS) {
114                 return false;
115         }
116         MAPIFreeBuffer(properties_array.lpProps);
117
118         /* Release */
119         mapi_object_release(&obj_store);
120
121         return true;
122 }
123
124
125 /**
126    \details Test the GetPropList (0x9) operation
127
128    This function:
129    -# Log on the user private mailbox
130    -# Retrieve the list of properties associated to the store object object
131
132    \param mt pointer on the top-level mapitest structure
133    
134    \return true on success, otherwise false
135  */
136 _PUBLIC_ bool mapitest_oxcprpt_GetPropList(struct mapitest *mt)
137 {
138         enum MAPISTATUS         retval;
139         mapi_object_t           obj_store;
140         struct SPropTagArray    *SPropTagArray;
141
142         /* Step 1. Logon Private Mailbox */
143         mapi_object_init(&obj_store);
144         retval = OpenMsgStore(mt->session, &obj_store);
145         mapitest_print_retval(mt, "OpenMsgStore");
146         if (retval != MAPI_E_SUCCESS) {
147                 return false;
148         }
149
150         /* Step 2. GetPropList operation */
151         SPropTagArray = talloc_zero(mt->mem_ctx, struct SPropTagArray);
152         retval = GetPropList(&obj_store, SPropTagArray);
153         mapitest_print_retval(mt, "GetPropList");
154         MAPIFreeBuffer(SPropTagArray);
155         if (retval != MAPI_E_SUCCESS) {
156                 return false;
157         }
158
159         /* Release */
160         mapi_object_release(&obj_store);
161
162         return true;
163 }
164
165
166 /**
167    \details Test the SetProps (0xa) operation
168
169    This function:
170    -# Logon Private mailbox
171    -# Use GetProps to retrieve the mailbox name
172    -# Change it using SetProps
173    -# Reset the mailbox name to its original value
174
175    \param mt pointer to the top-level mapitest structure
176
177    \return true on success, otherwise false
178  */
179 _PUBLIC_ bool mapitest_oxcprpt_SetProps(struct mapitest *mt)
180 {
181         enum MAPISTATUS         retval;
182         mapi_object_t           obj_store;
183         struct SPropValue       *lpProps;
184         struct SPropValue       lpProp[1];
185         struct SPropTagArray    *SPropTagArray;
186         const char              *mailbox = NULL;
187         const char              *new_mailbox = NULL;
188         uint32_t                cValues;
189
190         /* Step 1. Logon Private Mailbox */
191         mapi_object_init(&obj_store);
192         retval = OpenMsgStore(mt->session, &obj_store);
193         mapitest_print_retval_step_fmt(mt, "1.", "OpenMsgStore", "(%s)", "Logon Private Mailbox");
194         if (retval != MAPI_E_SUCCESS) {
195                 return false;
196         }
197
198         /* Step 2: GetProps, retrieve mailbox name */
199         SPropTagArray = set_SPropTagArray(mt->mem_ctx, 0x1, PR_DISPLAY_NAME);
200         retval = GetProps(&obj_store, SPropTagArray, &lpProps, &cValues);
201         mapitest_print_retval_step_fmt(mt, "2.", "GetProps", "(%s)", "Retrieve the mailbox name");
202         if (retval != MAPI_E_SUCCESS) {
203                 return false;
204         }
205         MAPIFreeBuffer(SPropTagArray);
206
207         if (cValues && lpProps[0].value.lpszA) {
208                 mailbox = lpProps[0].value.lpszA;
209                 mapitest_print(mt, "* Step 2. Mailbox name = %s\n", mailbox);
210         } else {
211                 mapitest_print(mt, MT_ERROR, "* Step 2 - GetProps: No mailbox name\n");
212                 return false;
213         }
214
215         /* Step 2.1: SetProps with new value */
216         cValues = 1;
217         new_mailbox = talloc_asprintf(mt->mem_ctx, "%s [MAPITEST]", mailbox);
218         set_SPropValue_proptag(&lpProp[0], PR_DISPLAY_NAME, 
219                                (const void *) new_mailbox);
220         retval = SetProps(&obj_store, lpProp, cValues);
221         mapitest_print_retval_step_fmt(mt, "2.1.", "SetProps", "(%s)", "NEW mailbox name");
222
223         /* Step 2.2: Double check with GetProps */
224         SPropTagArray = set_SPropTagArray(mt->mem_ctx, 0x1, PR_DISPLAY_NAME);
225         retval = GetProps(&obj_store, SPropTagArray, &lpProps, &cValues);
226         MAPIFreeBuffer(SPropTagArray);
227         if (lpProps[0].value.lpszA) {
228                 if (!strncmp(new_mailbox, lpProps[0].value.lpszA, strlen(lpProps[0].value.lpszA))) {
229                         mapitest_print(mt, "* Step 2.2 - Check: NEW mailbox name - [SUCCESS] (%s)\n", lpProps[0].value.lpszA);
230                 } else {
231                         mapitest_print(mt, "* Step 2.2 - Check: NEW mailbox name [FAILURE]\n");
232                 }
233         }
234         MAPIFreeBuffer((void *)new_mailbox);
235
236         /* Step 3.1: Reset mailbox to its original value */
237         cValues = 1;
238         set_SPropValue_proptag(&lpProp[0], PR_DISPLAY_NAME, (const void *)mailbox);
239         retval = SetProps(&obj_store, lpProp, cValues);
240         mapitest_print_retval_step_fmt(mt, "3.1.", "SetProps", "(%s)", "OLD mailbox name");
241         
242         /* Step 3.2: Double check with GetProps */
243         SPropTagArray = set_SPropTagArray(mt->mem_ctx, 0x1, PR_DISPLAY_NAME);
244         retval = GetProps(&obj_store, SPropTagArray, &lpProps, &cValues);
245         MAPIFreeBuffer(SPropTagArray);
246         if (lpProps[0].value.lpszA) {
247                 if (!strncmp(mailbox, lpProps[0].value.lpszA, strlen(lpProps[0].value.lpszA))) {
248                         mapitest_print(mt, "* Step 3.2 - Check: OLD mailbox name [SUCCESS]\n");
249                 } else {
250                         mapitest_print(mt, "* Step 3.2 - Check: OLD mailbox name, [FAILURE]\n");
251                 }
252         }
253
254         /* Release */
255         mapi_object_release(&obj_store);
256
257         return true;
258 }
259
260
261 /**
262    \details Test the DeleteProps (0xb) operation)
263
264    This function:
265    -# Opens the mailbox
266    -# Create a test folder
267    -# Creates a reference email, and sets some properties on it
268    -# Delete properties from this message
269    -# Checks that properties got deleted
270    -# Deletes both email and the test folder
271
272    \todo It would be useful to test the problem return values
273
274    \param mt pointer to the top-level mapitest structure
275
276    \return true on success, otherwise false
277  */
278 _PUBLIC_ bool mapitest_oxcprpt_DeleteProps(struct mapitest *mt)
279 {
280         enum MAPISTATUS         retval;
281         mapi_object_t           obj_store;
282         mapi_object_t           obj_top_folder;
283         mapi_id_t               id_top_folder;
284         mapi_object_t           obj_ref_folder;
285         mapi_object_t           obj_ref_message;
286         const char              *name = NULL;
287         const char              *subject = NULL;
288         struct SPropValue       lpProp[3];
289         struct SPropTagArray    *SPropTagArray;
290         struct SPropValue       *lpProps;
291         uint32_t                cValues;
292         bool                    result;
293
294         /* Step 1. Logon Private Mailbox */
295         mapi_object_init(&obj_store);
296         retval = OpenMsgStore(mt->session, &obj_store);
297         mapitest_print_retval_step_fmt(mt, "1.", "OpenMsgStore", "(%s)", "Logon Private Mailbox");
298         if (retval != MAPI_E_SUCCESS) {
299                 return false;
300         }
301         mapi_object_init(&obj_top_folder);
302         retval = GetDefaultFolder(&obj_store, &id_top_folder, olFolderTopInformationStore);
303         retval = OpenFolder(&obj_store, id_top_folder, &obj_top_folder);
304         if (retval != MAPI_E_SUCCESS) {
305                 return false;
306         }
307
308         /* Step 2: Create reference folder */
309         mapi_object_init(&obj_ref_folder);
310         retval = CreateFolder(&obj_top_folder, FOLDER_GENERIC, MT_DIRNAME_TOP, NULL,
311                               OPEN_IF_EXISTS, &obj_ref_folder);
312         mapitest_print_retval_step_fmt(mt, "2.", "CreateFolder", "(%s)", "Create the test folder");
313         if (retval != MAPI_E_SUCCESS) {
314                 return false;
315         }
316
317         /* Step 3: Create reference message */
318         mapi_object_init(&obj_ref_message);
319         result = mapitest_common_message_create(mt, &obj_ref_folder, &obj_ref_message, MT_MAIL_SUBJECT);
320         mapitest_print_retval_step_fmt(mt, "3.1.", "mapitest_common_message_create", "(%s)", "Create a reference email");
321         if (result != true) {
322                 return false;
323         }
324         retval = SaveChangesMessage(&obj_ref_folder, &obj_ref_message, KeepOpenReadWrite);
325         if (retval != MAPI_E_SUCCESS) {
326                 return false;
327         }
328
329         name = talloc_asprintf(mt->mem_ctx, "Reference: %s", "display name");
330         subject = talloc_asprintf(mt->mem_ctx, "Reference: %s", "subject");
331         set_SPropValue_proptag(&lpProp[0], PR_DISPLAY_NAME, (const void *)name);
332         set_SPropValue_proptag(&lpProp[1], PR_CONVERSATION_TOPIC, (const void *)subject);
333         retval = SetProps(&obj_ref_message, lpProp, 2);
334         mapitest_print_retval_step_fmt(mt, "3.2.", "SetProps", "(%s)", "Set email properties");
335         if (retval != MAPI_E_SUCCESS) {
336                 return false;
337         }
338
339         /* Step 4: Double check with GetProps */
340         SPropTagArray = set_SPropTagArray(mt->mem_ctx, 0x2, PR_DISPLAY_NAME, PR_CONVERSATION_TOPIC);
341         retval = GetProps(&obj_ref_message, SPropTagArray, &lpProps, &cValues);
342         MAPIFreeBuffer(SPropTagArray);
343         if (lpProps[0].value.lpszA) {
344                 if (!strncmp(name, lpProps[0].value.lpszA, strlen(lpProps[0].value.lpszA))) {
345                         mapitest_print(mt, "* Step 4.1. - Check: Reference props set - [SUCCESS] (%s)\n",
346                                        lpProps[0].value.lpszA);
347                 } else {
348                         mapitest_print(mt, "* Step 4.1. - Check: Reference props set [FAILURE] (%s)\n",
349                                        lpProps[0].value.lpszA);
350                 }
351         }
352         if (lpProps[1].value.lpszA) {
353                 if (!strncmp(subject, lpProps[1].value.lpszA, strlen(lpProps[1].value.lpszA))) {
354                         mapitest_print(mt, "* Step 4.2. - Check: Reference props set - [SUCCESS] (%s)\n",
355                                        lpProps[1].value.lpszA);
356                 } else {
357                         mapitest_print(mt, "* Step 4.2. - Check: Reference props set [FAILURE] (%s)\n",
358                                        lpProps[1].value.lpszA);
359                 }
360         }
361         MAPIFreeBuffer(lpProps);
362
363         /* Step 5. Delete Properties */
364         SPropTagArray = set_SPropTagArray(mt->mem_ctx, 0x1, PR_CONVERSATION_TOPIC);
365         retval = DeleteProps(&obj_ref_message, SPropTagArray);
366         MAPIFreeBuffer(SPropTagArray);
367         mapitest_print_retval_step_fmt(mt, "5.", "DeleteProps", "PR_CONVERSATION_TOPIC");
368
369         /* Step 6. Double check with GetProps */
370         SPropTagArray = set_SPropTagArray(mt->mem_ctx, 0x1, PR_CONVERSATION_TOPIC);
371         retval = GetProps(&obj_ref_message, SPropTagArray, &lpProps, &cValues);
372         MAPIFreeBuffer(SPropTagArray);
373         if (get_SPropValue(lpProps, PR_CONVERSATION_TOPIC) == NULL) {
374                 mapitest_print(mt, "* Step 5.1. - GetProps verifier [SUCCESS]\n");
375         } else {
376                 mapitest_print(mt, "* Step 5.1. - GetProps verifier [FAILURE]:\n");
377         }
378         MAPIFreeBuffer(lpProps);
379
380         /* Step 7: cleanup folders */
381         retval = DeleteFolder(&obj_top_folder, mapi_object_get_id(&obj_ref_folder),
382                               DEL_FOLDERS | DEL_MESSAGES | DELETE_HARD_DELETE, NULL);
383         mapitest_print_retval_step(mt, "6.", "DeleteFolder", retval);
384
385         /* Release */
386         mapi_object_release(&obj_ref_message);
387         mapi_object_release(&obj_ref_folder);
388         mapi_object_release(&obj_top_folder);
389         mapi_object_release(&obj_store);
390
391
392         return true;
393 }
394
395
396 /**
397    \details Test the CopyProps (0x67) operation
398
399    This function:
400    -# Opens the mailbox
401    -# Creates a test folder
402    -# Creates a reference email, and sets some properties on it
403    -# Checks those properties are set correctly
404    -# Creates a second email, and sets some (different) properties on it
405    -# Checks those properties on the second folder are set correctly
406    -# Copies properties from the reference email to the second email (no overwrite)
407    -# Checks that properties on both emails are correct
408    -# Copies properties again, but with overwrite
409    -# Checks that properties on both emails are correct
410    -# Moves properties from the original email to the second email (no overwrite)
411    -# Checks that properties on both emails are correct
412    -# Deletes both emails and the test folder
413
414    \todo It would be useful to test the problem return values
415
416    \param mt pointer to the top-level mapitest structure
417
418    \return true on success, otherwise false
419  */
420 _PUBLIC_ bool mapitest_oxcprpt_CopyProps(struct mapitest *mt)
421 {
422         enum MAPISTATUS         retval;
423         mapi_object_t           obj_store;
424         mapi_object_t           obj_top_folder;
425         mapi_id_t               id_top_folder;
426         mapi_object_t           obj_ref_folder;
427         mapi_object_t           obj_ref_message;
428         const char              *name = NULL;
429         const char              *subject = NULL;
430         struct SPropValue       lpProp[3];
431         struct SPropTagArray    *SPropTagArray;
432         struct SPropValue       *lpProps;
433         uint32_t                cValues;
434         mapi_object_t           obj_target_message;
435         const char              *targ_name = NULL;
436         const char              *targ_dept = NULL;
437         uint16_t                problem_count = 999;
438         struct PropertyProblem  *problems = NULL;
439         bool                    result;
440
441         /* Step 1. Logon Private Mailbox */
442         mapi_object_init(&obj_store);
443         retval = OpenMsgStore(mt->session, &obj_store);
444         mapitest_print_retval_step_fmt(mt, "1.", "OpenMsgStore", "(%s)", "Logon Private Mailbox");
445         if (retval != MAPI_E_SUCCESS) {
446                 return false;
447         }
448         mapi_object_init(&obj_top_folder);
449         retval = GetDefaultFolder(&obj_store, &id_top_folder, olFolderTopInformationStore);
450         retval = OpenFolder(&obj_store, id_top_folder, &obj_top_folder);
451         if (retval != MAPI_E_SUCCESS) {
452                 return false;
453         }
454
455         /* Step 2: Create reference folder */
456         mapi_object_init(&obj_ref_folder);
457         retval = CreateFolder(&obj_top_folder, FOLDER_GENERIC, MT_DIRNAME_TOP, NULL,
458                               OPEN_IF_EXISTS, &obj_ref_folder);
459         mapitest_print_retval_step_fmt(mt, "2.", "CreateFolder", "(%s)", "Create the test folder");
460         if (retval != MAPI_E_SUCCESS) {
461                 return false;
462         }
463
464         /* Step 3: Create reference message */
465         mapi_object_init(&obj_ref_message);
466         result = mapitest_common_message_create(mt, &obj_ref_folder, &obj_ref_message, MT_MAIL_SUBJECT);
467         mapitest_print_retval_step_fmt(mt, "3.1.", "mapitest_common_message_create", "(%s)", "Create a reference email");
468         if (result != true) {
469                 return false;
470         }
471         retval = SaveChangesMessage(&obj_ref_folder, &obj_ref_message, KeepOpenReadWrite);
472         if (retval != MAPI_E_SUCCESS) {
473                 return false;
474         }
475
476         name = talloc_asprintf(mt->mem_ctx, "Reference: %s", "display name");
477         subject = talloc_asprintf(mt->mem_ctx, "Reference: %s", "subject");
478         set_SPropValue_proptag(&lpProp[0], PR_DISPLAY_NAME, (const void *)name);
479         set_SPropValue_proptag(&lpProp[1], PR_CONVERSATION_TOPIC, (const void *)subject);
480         retval = SetProps(&obj_ref_message, lpProp, 2);
481         mapitest_print_retval_step_fmt(mt, "3.2.", "SetProps", "(%s)", "Set email properties");
482         if (retval != MAPI_E_SUCCESS) {
483                 return false;
484         }
485
486         /* Step 4: Double check with GetProps */
487         SPropTagArray = set_SPropTagArray(mt->mem_ctx, 0x2, PR_DISPLAY_NAME, PR_CONVERSATION_TOPIC);
488         retval = GetProps(&obj_ref_message, SPropTagArray, &lpProps, &cValues);
489         MAPIFreeBuffer(SPropTagArray);
490         if (lpProps[0].value.lpszA) {
491                 if (!strncmp(name, lpProps[0].value.lpszA, strlen(lpProps[0].value.lpszA))) {
492                         mapitest_print(mt, "* Step 4.1. - Check: Reference props set - [SUCCESS] (%s)\n",
493                                        lpProps[0].value.lpszA);
494                 } else {
495                         mapitest_print(mt, "* Step 4.1. - Check: Reference props set [FAILURE] (%s)\n",
496                                        lpProps[0].value.lpszA);
497                 }
498         }
499         if (lpProps[1].value.lpszA) {
500                 if (!strncmp(subject, lpProps[1].value.lpszA, strlen(lpProps[1].value.lpszA))) {
501                         mapitest_print(mt, "* Step 4.2. - Check: Reference props set - [SUCCESS] (%s)\n",
502                                        lpProps[1].value.lpszA);
503                 } else {
504                         mapitest_print(mt, "* Step 4.2. - Check: Reference props set [FAILURE] (%s)\n",
505                                        lpProps[1].value.lpszA);
506                 }
507         }
508
509         /* Step 5: Create target message */
510         mapi_object_init(&obj_target_message);
511         result = mapitest_common_message_create(mt, &obj_ref_folder, &obj_target_message, MT_MAIL_SUBJECT);
512         mapitest_print_retval_step_fmt(mt, "5.1.", "mapitest_common_message_create", "(%s)", "Create target email");
513         if (result != true) {
514                 return false;
515         }
516         retval = SaveChangesMessage(&obj_ref_folder, &obj_target_message, KeepOpenReadWrite);
517         if (retval != MAPI_E_SUCCESS) {
518                 return false;
519         }
520
521         targ_name = talloc_asprintf(mt->mem_ctx, "Target: %s", "display name");
522         targ_dept = talloc_asprintf(mt->mem_ctx, "Target: %s", "department");
523         set_SPropValue_proptag(&lpProp[0], PR_DISPLAY_NAME, (const void *)targ_name);
524         set_SPropValue_proptag(&lpProp[1], PR_DEPARTMENT_NAME, (const void *)targ_dept);
525         retval = SetProps(&obj_target_message, lpProp, 2);
526         mapitest_print_retval_step_fmt(mt, "5.2.", "SetProps", "(%s)", "set properties on target email");
527         if (retval != MAPI_E_SUCCESS) {
528                 return false;
529         }
530
531         /* Step 6: Double check with GetProps */
532         SPropTagArray = set_SPropTagArray(mt->mem_ctx, 0x2, PR_DISPLAY_NAME, PR_DEPARTMENT_NAME);
533         retval = GetProps(&obj_target_message, SPropTagArray, &lpProps, &cValues);
534         MAPIFreeBuffer(SPropTagArray);
535         if (lpProps[0].value.lpszA) {
536                 if (!strncmp(targ_name, lpProps[0].value.lpszA, strlen(lpProps[0].value.lpszA))) {
537                         mapitest_print(mt, "* Step 6A - Check: Reference props set - [SUCCESS] (%s)\n",
538                                        lpProps[0].value.lpszA);
539                 } else {
540                         mapitest_print(mt, "* Step 6A - Check: Reference props set [FAILURE] (%s)\n",
541                                        lpProps[0].value.lpszA);
542                 }
543         }
544         if (lpProps[1].value.lpszA) {
545                 if (!strncmp(targ_dept, lpProps[1].value.lpszA, strlen(lpProps[1].value.lpszA))) {
546                         mapitest_print(mt, "* Step 6B - Check: Reference props set - [SUCCESS] (%s)\n",
547                                        lpProps[1].value.lpszA);
548                 } else {
549                         mapitest_print(mt, "* Step 6B - Check: Reference props set [FAILURE] (%s)\n",
550                                        lpProps[1].value.lpszA);
551                 }
552         }
553
554
555
556         /* Step 7: Copy properties, no overwrite */
557         SPropTagArray = set_SPropTagArray(mt->mem_ctx, 0x2, PR_DISPLAY_NAME, PR_CONVERSATION_TOPIC);
558         retval = CopyProps(&obj_ref_message, &obj_target_message, SPropTagArray, CopyFlagsNoOverwrite,
559                            &problem_count, &problems);
560         mapitest_print_retval_step_fmt(mt, "7.", "CopyProps", "(%s)", "no overwrite");
561         MAPIFreeBuffer(problems);
562         if (retval != MAPI_E_SUCCESS) {
563                 return false;
564         }
565         MAPIFreeBuffer(SPropTagArray);
566
567         /* Step 8: Double check with GetProps */
568         SPropTagArray = set_SPropTagArray(mt->mem_ctx, 0x2, PR_DISPLAY_NAME, PR_CONVERSATION_TOPIC);
569         retval = GetProps(&obj_ref_message, SPropTagArray, &lpProps, &cValues);
570         MAPIFreeBuffer(SPropTagArray);
571         if (lpProps[0].value.lpszA) {
572                 if (!strncmp(name, lpProps[0].value.lpszA, strlen(lpProps[0].value.lpszA))) {
573                         mapitest_print(mt, "* Step 8A - Check: Reference props still good - [SUCCESS] (%s)\n",
574                                        lpProps[0].value.lpszA);
575                 } else {
576                         mapitest_print(mt, "* Step 8A - Check: Reference props still good [FAILURE] (%s)\n",
577                                        lpProps[0].value.lpszA);
578                 }
579         }
580         if (lpProps[1].value.lpszA) {
581                 if (!strncmp(subject, lpProps[1].value.lpszA, strlen(lpProps[1].value.lpszA))) {
582                         mapitest_print(mt, "* Step 8B - Check: Reference props still good - [SUCCESS] (%s)\n",
583                                        lpProps[1].value.lpszA);
584                 } else {
585                         mapitest_print(mt, "* Step 8B - Check: Reference props still good [FAILURE] (%s)\n",
586                                        lpProps[1].value.lpszA);
587                 }
588         }
589         SPropTagArray = set_SPropTagArray(mt->mem_ctx, 0x3, PR_DISPLAY_NAME, PR_CONVERSATION_TOPIC, PR_DEPARTMENT_NAME);
590         retval = GetProps(&obj_target_message, SPropTagArray, &lpProps, &cValues);
591         MAPIFreeBuffer(SPropTagArray);
592         /* this one shouldn't be overwritten */
593         if (lpProps[0].value.lpszA) {
594                 if (!strncmp(targ_name, lpProps[0].value.lpszA, strlen(lpProps[0].value.lpszA))) {
595                         mapitest_print(mt, "* Step 8C - Check: Reference props copy - [SUCCESS] (%s)\n",
596                                        lpProps[0].value.lpszA);
597                 } else {
598                         mapitest_print(mt, "* Step 8C - Check: Reference props copy [FAILURE] (%s)\n",
599                                        lpProps[0].value.lpszA);
600                 }
601         }
602         /* this one should be copied */
603         if (lpProps[1].value.lpszA) {
604                 if (!strncmp(subject, lpProps[1].value.lpszA, strlen(lpProps[1].value.lpszA))) {
605                         mapitest_print(mt, "* Step 8D - Check: Reference props copy - [SUCCESS] (%s)\n",
606                                        lpProps[1].value.lpszA);
607                 } else {
608                         mapitest_print(mt, "* Step 8D - Check: Reference props copy [FAILURE] (%s)\n",
609                                        lpProps[1].value.lpszA);
610                 }
611         }
612         /* this one should be unchanged */
613         if (lpProps[2].value.lpszA) {
614                 if (!strncmp(targ_dept, lpProps[2].value.lpszA, strlen(lpProps[2].value.lpszA))) {
615                         mapitest_print(mt, "* Step 8E - Check: Reference props copy - [SUCCESS] (%s)\n",
616                                        lpProps[2].value.lpszA);
617                 } else {
618                         mapitest_print(mt, "* Step 8E - Check: Reference props copy [FAILURE] (%s)\n",
619                                        lpProps[2].value.lpszA);
620                 }
621         }
622
623         /* Step 9: Copy properties, with overwrite */
624         SPropTagArray = set_SPropTagArray(mt->mem_ctx, 0x2, PR_DISPLAY_NAME, PR_CONVERSATION_TOPIC);
625         retval = CopyProps(&obj_ref_message, &obj_target_message, SPropTagArray, 0x0,
626                            &problem_count, &problems);
627         MAPIFreeBuffer(SPropTagArray);
628         MAPIFreeBuffer(problems);
629         mapitest_print_retval_step_fmt(mt, "9.", "CopyProps", "(%s)", "with overwrite");
630         if (retval != MAPI_E_SUCCESS) {
631                 return false;
632         }
633
634         /* Step 10: Double check with GetProps */
635         SPropTagArray = set_SPropTagArray(mt->mem_ctx, 0x2, PR_DISPLAY_NAME, PR_CONVERSATION_TOPIC);
636         retval = GetProps(&obj_ref_message, SPropTagArray, &lpProps, &cValues);
637         MAPIFreeBuffer(SPropTagArray);
638         if (lpProps[0].value.lpszA) {
639                 if (!strncmp(name, lpProps[0].value.lpszA, strlen(lpProps[0].value.lpszA))) {
640                         mapitest_print(mt, "* Step 10A - Check: Reference props still good - [SUCCESS] (%s)\n",
641                                        lpProps[0].value.lpszA);
642                 } else {
643                         mapitest_print(mt, "* Step 10A - Check: Reference props still good [FAILURE] (%s)\n",
644                                        lpProps[0].value.lpszA);
645                 }
646         }
647         if (lpProps[1].value.lpszA) {
648                 if (!strncmp(subject, lpProps[1].value.lpszA, strlen(lpProps[1].value.lpszA))) {
649                         mapitest_print(mt, "* Step 10B - Check: Reference props still good - [SUCCESS] (%s)\n",
650                                        lpProps[1].value.lpszA);
651                 } else {
652                         mapitest_print(mt, "* Step 10B - Check: Reference props still good [FAILURE] (%s)\n",
653                                        lpProps[1].value.lpszA);
654                 }
655         }
656         SPropTagArray = set_SPropTagArray(mt->mem_ctx, 0x3, PR_DISPLAY_NAME, PR_CONVERSATION_TOPIC, PR_DEPARTMENT_NAME);
657         retval = GetProps(&obj_target_message, SPropTagArray, &lpProps, &cValues);
658         MAPIFreeBuffer(SPropTagArray);
659         /* this one should now be overwritten */
660         if (lpProps[0].value.lpszA) {
661                 if (!strncmp(name, lpProps[0].value.lpszA, strlen(lpProps[0].value.lpszA))) {
662                         mapitest_print(mt, "* Step 10C - Check: Reference props copy - [SUCCESS] (%s)\n",
663                                        lpProps[0].value.lpszA);
664                 } else {
665                         mapitest_print(mt, "* Step 10C - Check: Reference props copy [FAILURE] (%s)\n",
666                                        lpProps[0].value.lpszA);
667                 }
668         }
669         /* this one should be copied */
670         if (lpProps[1].value.lpszA) {
671                 if (!strncmp(subject, lpProps[1].value.lpszA, strlen(lpProps[1].value.lpszA))) {
672                         mapitest_print(mt, "* Step 10D - Check: Reference props copy - [SUCCESS] (%s)\n",
673                                        lpProps[1].value.lpszA);
674                 } else {
675                         mapitest_print(mt, "* Step 10D - Check: Reference props copy [FAILURE] (%s)\n",
676                                        lpProps[1].value.lpszA);
677                 }
678         }
679         /* this one should be unchanged */
680         if (lpProps[2].value.lpszA) {
681                 if (!strncmp(targ_dept, lpProps[2].value.lpszA, strlen(lpProps[2].value.lpszA))) {
682                         mapitest_print(mt, "* Step 10E - Check: Reference props copy - [SUCCESS] (%s)\n",
683                                        lpProps[2].value.lpszA);
684                 } else {
685                         mapitest_print(mt, "* Step 10E - Check: Reference props copy [FAILURE] (%s)\n",
686                                        lpProps[2].value.lpszA);
687                 }
688         }
689
690         if ( mt->info.rgwServerVersion[0] >= Exchange2010SP0Version ) {
691                 /* the combination of CopyFlagsNoOverwrite|CopyFlagsMove isn't support in Exchange2010 */
692                 goto cleanup;
693         }
694             
695         /* Step 11: Move properties, no overwrite */
696         SPropTagArray = set_SPropTagArray(mt->mem_ctx, 0x2, PR_DISPLAY_NAME, PR_CONVERSATION_TOPIC);
697         retval = CopyProps(&obj_ref_message, &obj_target_message, SPropTagArray, CopyFlagsNoOverwrite|CopyFlagsMove,
698                            &problem_count, &problems);
699         MAPIFreeBuffer(SPropTagArray);
700         if (problem_count) {
701                 MAPIFreeBuffer(problems);
702         }
703         mapitest_print_retval_step_fmt(mt, "11.", "CopyProps", "(%s)", "move");
704         if (retval != MAPI_E_SUCCESS) {
705                 return false;
706         }
707
708         /* Step 12: Double check with GetProps */
709         SPropTagArray = set_SPropTagArray(mt->mem_ctx, 0x2, PR_DISPLAY_NAME, PR_CONVERSATION_TOPIC);
710         retval = GetProps(&obj_ref_message, SPropTagArray, &lpProps, &cValues);
711         MAPIFreeBuffer(SPropTagArray);
712         if (cValues == 2) {
713                 mapitest_print(mt, "* Step 12A - Properties removed [SUCCESS]\n");
714         } else {
715                 mapitest_print(mt, "* Step 12A - Properties removed [FAILURE]\n");
716         }
717         SPropTagArray = set_SPropTagArray(mt->mem_ctx, 0x3, PR_DISPLAY_NAME, PR_CONVERSATION_TOPIC, PR_DEPARTMENT_NAME);
718         retval = GetProps(&obj_target_message, SPropTagArray, &lpProps, &cValues);
719         MAPIFreeBuffer(SPropTagArray);
720         if (lpProps[0].value.lpszA) {
721                 if (!strncmp(name, lpProps[0].value.lpszA, strlen(lpProps[0].value.lpszA))) {
722                         mapitest_print(mt, "* Step 12B - Check: Reference props move - [SUCCESS] (%s)\n",
723                                        lpProps[0].value.lpszA);
724                 } else {
725                         mapitest_print(mt, "* Step 12B - Check: Reference props move [FAILURE] (%s)\n",
726                                        lpProps[0].value.lpszA);
727                 }
728         }
729         if (lpProps[1].value.lpszA) {
730                 if (!strncmp(subject, lpProps[1].value.lpszA, strlen(lpProps[1].value.lpszA))) {
731                         mapitest_print(mt, "* Step 12C - Check: Reference props move - [SUCCESS] (%s)\n",
732                                        lpProps[1].value.lpszA);
733                 } else {
734                         mapitest_print(mt, "* Step 12C - Check: Reference props move [FAILURE] (%s)\n",
735                                        lpProps[1].value.lpszA);
736                 }
737         }
738         if (lpProps[2].value.lpszA) {
739                 if (!strncmp(targ_dept, lpProps[2].value.lpszA, strlen(lpProps[2].value.lpszA))) {
740                         mapitest_print(mt, "* Step 12D - Check: Reference props move - [SUCCESS] (%s)\n",
741                                        lpProps[2].value.lpszA);
742                 } else {
743                         mapitest_print(mt, "* Step 12D - Check: Reference props move [FAILURE] (%s)\n",
744                                        lpProps[2].value.lpszA);
745                 }
746         }
747
748         cleanup:
749
750         /* Cleanup reference strings */
751         MAPIFreeBuffer((void *)subject);
752         MAPIFreeBuffer((void *)name);
753         MAPIFreeBuffer((void *)targ_name);
754         MAPIFreeBuffer((void *)targ_dept);
755
756         /* Step 13: cleanup folders */
757         retval = DeleteFolder(&obj_top_folder, mapi_object_get_id(&obj_ref_folder),
758                               DEL_FOLDERS | DEL_MESSAGES | DELETE_HARD_DELETE, NULL);
759         mapitest_print_retval_step(mt, "13.1.", "DeleteFolder", retval);
760
761         /* Release */
762         mapi_object_release(&obj_ref_message);
763         mapi_object_release(&obj_ref_folder);
764         mapi_object_release(&obj_top_folder);
765         mapi_object_release(&obj_store);
766
767
768         return true;
769 }
770
771
772
773 /**
774    \details Test Stream operations. This test uses related stream
775    operations: OpenStream (0x2b), SetStreamSize (0x2f), WriteStream
776    (0x2d), CommitStream (0x5d), ReadStream (0x2c), SeekStream (0x2e),
777    LockRegionStream (0x5b), UnlockRegionStream (0x5c), CloneStream (0x3b)
778    
779    This function:
780    -# Logon 
781    -# Open Outbox folder
782    -# Create message
783    -# Create attachment and set properties
784    -# Open the stream
785    -# Set the stream size
786    -# Write into the stream
787    -# Commit the stream
788    -# Save the message
789    -# Get stream size and compare values
790    -# Open the stream again with different permissions
791    -# Read the stream and compare buffers
792    -# SeekStream at 0x1000 from the end of the stream
793    -# Read the 0x1000 last bytes and check if it matches
794    -# Lock a range of the stream
795    -# TODO: test if the locking works
796    -# Unlock a range of the stream
797    -# Clone the stream
798    -# Delete the message;
799
800    \param mt pointer to the top-level mapitest structure
801
802    \return true on success, otherwise -1
803  */
804 _PUBLIC_ bool mapitest_oxcprpt_Stream(struct mapitest *mt)
805 {
806         enum MAPISTATUS         retval;
807         bool                    ret = true;
808         mapi_object_t           obj_store;
809         mapi_object_t           obj_folder;
810         mapi_object_t           obj_message;
811         mapi_object_t           obj_attach;
812         mapi_object_t           obj_stream;
813         mapi_object_t           obj_stream_clone;
814         mapi_id_t               id_folder;
815         DATA_BLOB               data;
816         struct SPropValue       attach[3];
817         char                    *stream = NULL;
818         char                    *out_stream = NULL;
819         uint32_t                stream_len = 0x32146;
820         unsigned char           buf[MT_STREAM_MAX_SIZE];
821         uint32_t                StreamSize = 0;
822         uint16_t                read_size = 0;
823         uint16_t                write_len = 0;
824         uint32_t                len = 0;
825         uint32_t                offset = 0;
826         mapi_id_t               id_msgs[1];
827         uint32_t                i;
828         uint64_t                NewPosition;
829
830         stream = mapitest_common_genblob(mt->mem_ctx, stream_len);
831         if (stream == NULL) {
832                 return false;
833         }
834
835         /* Step 1. Logon */
836         mapi_object_init(&obj_store);
837         retval = OpenMsgStore(mt->session, &obj_store);
838         mapitest_print_retval(mt, "OpenMsgStore");
839         if (retval != MAPI_E_SUCCESS) {
840                 return false;
841         }
842
843         /* Step 2. Open Inbox folder */
844         retval = GetDefaultFolder(&obj_store, &id_folder, olFolderInbox);
845         mapitest_print_retval(mt, "GetDefaultFolder");
846         if (retval != MAPI_E_SUCCESS) {
847                 return false;
848         }
849
850         mapi_object_init(&obj_folder);
851         retval = OpenFolder(&obj_store, id_folder, &obj_folder);
852         mapitest_print_retval(mt, "OpenFolder");
853         if (retval != MAPI_E_SUCCESS) {
854                 return false;
855         }
856
857         /* Step 3. Create the message */
858         mapi_object_init(&obj_message);
859         ret = mapitest_common_message_create(mt, &obj_folder, &obj_message, MT_MAIL_SUBJECT);
860         mapitest_print_retval(mt, "Message Creation");
861         if (ret != true) {
862                 return false;
863         }
864
865         /* Step 4. Create the attachment */
866         mapi_object_init(&obj_attach);
867         retval = CreateAttach(&obj_message, &obj_attach);
868         mapitest_print_retval(mt, "CreateAttach");
869         if (retval != MAPI_E_SUCCESS) {
870                 ret = false;
871         }
872
873         attach[0].ulPropTag = PR_ATTACH_METHOD;
874         attach[0].value.l = ATTACH_BY_VALUE;
875         attach[1].ulPropTag = PR_RENDERING_POSITION;
876         attach[1].value.l = 0;
877         attach[2].ulPropTag = PR_ATTACH_FILENAME;
878         attach[2].value.lpszA = MT_MAIL_ATTACH;
879
880         retval = SetProps(&obj_attach, attach, 3);
881         if (retval != MAPI_E_SUCCESS) {
882                 ret = false;
883         }
884
885         /* Step 5. Open the stream */
886         mapi_object_init(&obj_stream);
887         retval = OpenStream(&obj_attach, PR_ATTACH_DATA_BIN, 2, &obj_stream);
888         mapitest_print_retval(mt, "OpenStream");
889         if (retval != MAPI_E_SUCCESS) {
890                 ret = false;
891         }
892
893         /* Step 6. Set the stream size */
894         retval = SetStreamSize(&obj_stream, (uint64_t) stream_len);
895         mapitest_print_retval(mt, "SetStreamSize");
896         if (retval != MAPI_E_SUCCESS) {
897                 ret = false;
898         }
899
900         /* Step 7. Write the stream */
901         write_len = 0;
902
903         StreamSize = stream_len;
904
905         for (offset = 0, len = MT_STREAM_MAX_SIZE, i = 0; StreamSize; i++) {
906                 data.length = len;
907                 data.data = (uint8_t *)stream + offset;
908                 retval = WriteStream(&obj_stream, &data, &write_len);
909                 mapitest_print_retval_fmt(mt, "WriteStream", "[%d] (0x%x bytes written)", i, write_len);
910                 if (retval != MAPI_E_SUCCESS) {
911                         ret = false;
912                         break;
913                 }
914
915                 StreamSize -= write_len;
916                 if (StreamSize > MT_STREAM_MAX_SIZE) {
917                         offset += MT_STREAM_MAX_SIZE;
918                 } else {
919                         offset += write_len;
920                         len = StreamSize;
921                 }
922         }
923
924         /* Step 8. Commit the stream */
925         retval = CommitStream(&obj_stream);
926         mapitest_print_retval(mt, "CommitStream");
927         if (retval != MAPI_E_SUCCESS) {
928                 ret = false;
929         }
930
931         /* Step 9. Save the attachment */
932         retval = SaveChangesAttachment(&obj_message, &obj_attach, KeepOpenReadOnly);
933         mapitest_print_retval(mt, "SaveChangesAttachment");
934         if (retval != MAPI_E_SUCCESS) {
935                 ret = false;
936         }
937
938         retval = SaveChangesMessage(&obj_folder, &obj_message, KeepOpenReadOnly);
939         mapitest_print_retval(mt, "SaveChangesMessage");
940         if (retval != MAPI_E_SUCCESS) {
941                 ret = false;
942         }
943
944         /* Step 10. Get stream size */
945         retval = GetStreamSize(&obj_stream, &StreamSize);
946         mapitest_print_retval(mt, "GetStreamSize");
947         if (retval != MAPI_E_SUCCESS) {
948                 ret = false;
949         }
950         mapitest_print(mt, "* %-35s: %s\n", "StreamSize comparison", 
951                        (StreamSize == stream_len) ? "[PASSED]" : "[FAILURE]");
952
953         /* Step 11. Read the stream */
954         mapi_object_release(&obj_stream);
955         mapi_object_init(&obj_stream);
956
957         retval = OpenStream(&obj_attach, PR_ATTACH_DATA_BIN, 0, &obj_stream);
958         mapitest_print_retval(mt, "OpenStream");
959         if (retval != MAPI_E_SUCCESS) {
960                 ret = false;
961         }
962
963         offset = 0;
964         out_stream = talloc_size(mt->mem_ctx, StreamSize + 1);
965         do {
966                 retval = ReadStream(&obj_stream, buf, MT_STREAM_MAX_SIZE, &read_size);
967                 mapitest_print_retval_fmt(mt, "ReadStream", "(0x%x bytes read)", read_size);
968                 memcpy(out_stream + offset, buf, read_size);
969                 offset += read_size;
970                 if (retval != MAPI_E_SUCCESS) {
971                         ret = false;
972                         break;
973                 }
974         } while (read_size && (offset != StreamSize));
975         out_stream[offset] = '\0';
976
977         if (offset) {
978                 if (!strcmp(stream, out_stream)) {
979                         mapitest_print(mt, "* %-35s: [IN,OUT] stream [PASSED]\n", "Comparison");
980                 } else {
981                         mapitest_print(mt, "* %-35s: [IN,OUT] stream [FAILURE]\n", "Comparison");
982
983                 }
984         }
985
986         /* Step 12. SeekStream from the end of the stream */
987         retval = SeekStream(&obj_stream, 0x2, (uint64_t) -0x1000, &NewPosition);
988         mapitest_print_retval(mt, "SeekStream");
989         if (retval != MAPI_E_SUCCESS) {
990                 ret = false;
991         }
992
993
994         talloc_free(out_stream);
995         out_stream = talloc_size(mt->mem_ctx, 0x1001);
996         retval = ReadStream(&obj_stream, (uint8_t *)out_stream, 0x1000, &read_size);
997         out_stream[read_size] = '\0';
998         mapitest_print_retval_fmt(mt, "ReadStream", "(0x%x bytes read)", read_size);
999         if (retval != MAPI_E_SUCCESS) {
1000                 ret = false;
1001         }
1002
1003         if (read_size && !strcmp(out_stream, stream + StreamSize - read_size)) {
1004                 mapitest_print(mt, "* %-35s: [SUCCESS]\n", "Comparison");
1005         } else {
1006                 mapitest_print(mt, "* %-35s: [FAILURE]\n", "Comparison");
1007         }
1008
1009         mapi_object_init(&obj_stream_clone);
1010         if (mt->info.rgwServerVersion[0] >= Exchange2010SP0Version) {
1011                 mapitest_print(mt, "* SKIPPING test for LockRegionStream, UnlockRegionStream and CloneStream\n");
1012         } else {
1013                 /* Step 13. Lock a region */
1014                 retval = LockRegionStream(&obj_stream, 0x2000, 0x1000, 0x0);
1015                 mapitest_print_retval(mt, "LockRegionStream");
1016                 if (retval != MAPI_E_SUCCESS) {
1017                         ret = false;
1018                 }
1019
1020                 /* TODO: Step 14. Test the locking */
1021
1022
1023                 /* Step 15. Unlock the region */
1024                 retval = UnlockRegionStream(&obj_stream, 0x2000, 0x1000, 0x0);
1025                 mapitest_print_retval(mt, "UnlockRegionStream");
1026                 if (retval != MAPI_E_SUCCESS) {
1027                         ret = false;
1028                 }
1029
1030                 /* Step 16. Clone the stream */
1031                 retval = CloneStream(&obj_stream, &obj_stream_clone);
1032                 mapitest_print_retval(mt, "CloneStream");
1033                 if (retval != MAPI_E_SUCCESS) {
1034                         ret = false;
1035                 }
1036
1037                 /* Step 17. Test the clone */
1038                 retval = SeekStream(&obj_stream_clone, 0x0, 0, &NewPosition);
1039                 mapitest_print_retval(mt, "SeekStream");
1040                 if (retval != MAPI_E_SUCCESS) {
1041                         ret = false;
1042                 }
1043                 retval = ReadStream(&obj_stream_clone, buf, MT_STREAM_MAX_SIZE, &read_size);
1044                 mapitest_print_retval_fmt(mt, "ReadStream", "(0x%x bytes read)", read_size);
1045                 if (retval != MAPI_E_SUCCESS) {
1046                         ret = false;
1047                 }
1048         }
1049
1050         /* Delete the message */
1051         errno = 0;
1052         id_msgs[0] = mapi_object_get_id(&obj_message);
1053         retval = DeleteMessage(&obj_folder, id_msgs, 1);
1054         mapitest_print_retval(mt, "DeleteMessage");
1055         if (retval != MAPI_E_SUCCESS) {
1056                 ret = false;
1057         }
1058
1059         /* Release */
1060         mapi_object_release(&obj_stream_clone);
1061         mapi_object_release(&obj_stream);
1062         mapi_object_release(&obj_attach);
1063         mapi_object_release(&obj_message);
1064         mapi_object_release(&obj_folder);
1065         mapi_object_release(&obj_store);
1066
1067         talloc_free(stream);
1068         talloc_free(out_stream);
1069
1070         return ret;
1071 }
1072
1073
1074 /**
1075    \details Test the CopyToStream (0x3a) operation
1076
1077    This function:
1078    -# Logon the mailbox
1079    -# Open the inbox folder
1080    -# Create a sample messages with an attachment
1081    -# Create 2 streams
1082    -# Fill the first stream with random data
1083    -# Seek stream positions to the beginning
1084    -# CopyToStream data from first stream to the second stream
1085    -# Read dst stream and compare with src stream
1086    -# Delete the message
1087    
1088    \param mt pointer to the top-level mapitest structure
1089
1090    \return true on success, otherwise false
1091  */
1092 _PUBLIC_ bool mapitest_oxcprpt_CopyToStream(struct mapitest *mt)
1093 {
1094         enum MAPISTATUS         retval;
1095         bool                    ret = true;
1096         mapi_object_t           obj_store;
1097         mapi_object_t           obj_folder;
1098         mapi_object_t           obj_message;
1099         mapi_object_t           obj_attach;
1100         mapi_object_t           obj_attach2;
1101         mapi_object_t           obj_stream;
1102         mapi_object_t           obj_stream2;
1103         mapi_id_t               id_folder;
1104         mapi_id_t               id_msgs[1];
1105         struct SPropValue       attach[3];
1106         DATA_BLOB               data;
1107         char                    *stream = NULL;
1108         char                    *dst_stream = NULL;
1109         uint32_t                stream_len = 0x32146;
1110         unsigned char           buf[MT_STREAM_MAX_SIZE];
1111         uint32_t                StreamSize = 0;
1112         uint16_t                write_len = 0;
1113         uint16_t                read_size = 0;
1114         uint32_t                len = 0;
1115         uint32_t                offset = 0;
1116         uint32_t                i;
1117         uint64_t                ReadByteCount = 0;
1118         uint64_t                WrittenByteCount = 0;
1119         uint64_t                NewPosition = 0;
1120
1121         stream = mapitest_common_genblob(mt->mem_ctx, stream_len);
1122         if (stream == NULL) {
1123                 return false;
1124         }
1125
1126         /* Step 1. Logon */
1127         mapi_object_init(&obj_store);
1128         retval = OpenMsgStore(mt->session, &obj_store);
1129         mapitest_print_retval(mt, "OpenMsgStore");
1130         if (retval != MAPI_E_SUCCESS) {
1131                 return false;
1132         }
1133
1134         /* Step 2. Open Inbox folder */
1135         retval = GetDefaultFolder(&obj_store, &id_folder, olFolderInbox);
1136         mapitest_print_retval(mt, "GetDefaultFolder");
1137         if (retval != MAPI_E_SUCCESS) {
1138                 return false;
1139         }
1140
1141         mapi_object_init(&obj_folder);
1142         retval = OpenFolder(&obj_store, id_folder, &obj_folder);
1143         mapitest_print_retval(mt, "OpenFolder");
1144         if (retval != MAPI_E_SUCCESS) {
1145                 return false;
1146         }
1147
1148         /* Step 3. Create the message */
1149         mapi_object_init(&obj_message);
1150         ret = mapitest_common_message_create(mt, &obj_folder, &obj_message, MT_MAIL_SUBJECT);
1151         mapitest_print_retval(mt, "Message Creation");
1152         if (ret != true) {
1153                 return false;
1154         }
1155
1156         /* Step 4. Create the first attachment */
1157         mapi_object_init(&obj_attach);
1158         retval = CreateAttach(&obj_message, &obj_attach);
1159         mapitest_print_retval(mt, "CreateAttach");
1160         if (retval != MAPI_E_SUCCESS) {
1161                 ret = false;
1162         }
1163
1164         attach[0].ulPropTag = PR_ATTACH_METHOD;
1165         attach[0].value.l = ATTACH_BY_VALUE;
1166         attach[1].ulPropTag = PR_RENDERING_POSITION;
1167         attach[1].value.l = 0;
1168         attach[2].ulPropTag = PR_ATTACH_FILENAME;
1169         attach[2].value.lpszA = MT_MAIL_ATTACH;
1170
1171         retval = SetProps(&obj_attach, attach, 3);
1172         if (retval != MAPI_E_SUCCESS) {
1173                 ret = false;
1174         }
1175
1176         /* Step 5. Open the stream */
1177         mapi_object_init(&obj_stream);
1178         retval = OpenStream(&obj_attach, PR_ATTACH_DATA_BIN, 2, &obj_stream);
1179         mapitest_print_retval(mt, "OpenStream");
1180         if (retval != MAPI_E_SUCCESS) {
1181                 ret = false;
1182         }
1183
1184         /* Step 6. Set the stream size */
1185         retval = SetStreamSize(&obj_stream, (uint64_t) stream_len);
1186         mapitest_print_retval(mt, "SetStreamSize");
1187         if (retval != MAPI_E_SUCCESS) {
1188                 ret = false;
1189         }
1190
1191         /* Step 7. Write the stream */
1192         write_len = 0;
1193
1194         StreamSize = stream_len;
1195
1196         for (offset = 0, len = MT_STREAM_MAX_SIZE, i = 0; StreamSize; i++) {
1197                 data.length = len;
1198                 data.data = (uint8_t *)stream + offset;
1199                 retval = WriteStream(&obj_stream, &data, &write_len);
1200                 mapitest_print_retval_fmt(mt, "WriteStream", "[%d] (0x%x bytes written)", i, write_len);
1201
1202                 StreamSize -= write_len;
1203                 if (StreamSize > MT_STREAM_MAX_SIZE) {
1204                         offset += MT_STREAM_MAX_SIZE;
1205                 } else {
1206                         offset += write_len;
1207                         len = StreamSize;
1208                 }
1209         }
1210
1211         /* Step 8. Commit the stream */
1212         retval = CommitStream(&obj_stream);
1213         mapitest_print_retval(mt, "CommitStream");
1214         if (retval != MAPI_E_SUCCESS) {
1215                 ret = false;
1216         }
1217
1218         /* Step 9. Save the attachment */
1219         retval = SaveChangesAttachment(&obj_message, &obj_attach, KeepOpenReadOnly);
1220         mapitest_print_retval(mt, "SaveChangesAttachment");
1221
1222         /* Step 10. Create the second attachment */
1223         mapi_object_init(&obj_attach2);
1224         retval = CreateAttach(&obj_message, &obj_attach2);
1225         mapitest_print_retval(mt, "CreateAttach");
1226         if (retval != MAPI_E_SUCCESS) {
1227                 ret = false;
1228         }
1229
1230         attach[0].ulPropTag = PR_ATTACH_METHOD;
1231         attach[0].value.l = ATTACH_BY_VALUE;
1232         attach[1].ulPropTag = PR_RENDERING_POSITION;
1233         attach[1].value.l = 0;
1234         attach[2].ulPropTag = PR_ATTACH_FILENAME;
1235         attach[2].value.lpszA = MT_MAIL_ATTACH2;
1236
1237         retval = SetProps(&obj_attach2, attach, 3);
1238         if (retval != MAPI_E_SUCCESS) {
1239                 ret = false;
1240         }
1241
1242         /* Step 11. Open the dst stream */
1243         mapi_object_init(&obj_stream2);
1244         retval = OpenStream(&obj_attach2, PR_ATTACH_DATA_BIN, 2, &obj_stream2);
1245         mapitest_print_retval(mt, "OpenStream");
1246         if (retval != MAPI_E_SUCCESS) {
1247                 ret = false;
1248         }
1249
1250         /* Step 12. Get src stream size */
1251         retval = GetStreamSize(&obj_stream, &StreamSize);
1252         mapitest_print_retval_fmt(mt, "GetStreamSize", "(%s: 0x%x)", "Src", StreamSize);
1253         if (retval != MAPI_E_SUCCESS) {
1254                 ret = false;
1255         }
1256
1257         /* Step 13. Reset streams positions to the beginning */
1258         retval = SeekStream(&obj_stream, 0, 0, &NewPosition);
1259         mapitest_print_retval_fmt(mt, "SeekStream", "(%s)", "Src");
1260         if (retval != MAPI_E_SUCCESS) {
1261                 ret = false;
1262         }
1263
1264         retval = SeekStream(&obj_stream2, 0, 0, &NewPosition);
1265         mapitest_print_retval_fmt(mt, "SeekStream", "(%s)", "Dst");
1266         if (retval != MAPI_E_SUCCESS) {
1267                 ret = false;
1268         }
1269
1270         /* Step 14. Copy src to dst stream */
1271         retval = CopyToStream(&obj_stream, &obj_stream2, StreamSize, &ReadByteCount, &WrittenByteCount);
1272         mapitest_print_retval(mt, "CopyToStream");
1273         if (retval != MAPI_E_SUCCESS) {
1274                 ret = false;
1275         }
1276
1277         /* Step 14. Save the attachment */
1278         retval = SaveChangesAttachment(&obj_message, &obj_attach2, KeepOpenReadOnly);
1279         mapitest_print_retval(mt, "SaveChangesAttachment");
1280         retval = SaveChangesMessage(&obj_folder, &obj_message, KeepOpenReadOnly);
1281         mapitest_print_retval(mt, "SaveChangesMessage");
1282         if (retval != MAPI_E_SUCCESS) {
1283                 ret = false;
1284         }
1285
1286         /* Step 15. Compare values */
1287         mapitest_print(mt, "* %-35s: 0x%llx - 0x%llx %s\n", "Read/Write bytes comparison",
1288                        ReadByteCount, WrittenByteCount, 
1289                        (ReadByteCount == WrittenByteCount) ? "[SUCCESS]" : "[FAILURE]");
1290
1291
1292         /* Step 16. Get dst stream size */
1293         retval = GetStreamSize(&obj_stream2, &StreamSize);
1294         mapitest_print_retval_fmt(mt, "GetStreamSize", "(%s: 0x%x)", "Dst", StreamSize);
1295         if (retval != MAPI_E_SUCCESS) {
1296                 ret = false;
1297         }
1298
1299         retval = SeekStream(&obj_stream2, 0, 0, &NewPosition);
1300         mapitest_print_retval_fmt(mt, "SeekStream", "(%s)", "Dst");
1301         if (retval != MAPI_E_SUCCESS) {
1302                 ret = false;
1303         }
1304
1305         /* Step 17. Read the dst stream */
1306         offset = 0;
1307         dst_stream = talloc_size(mt->mem_ctx, StreamSize + 1);
1308         do {
1309                 retval = ReadStream(&obj_stream2, buf, MT_STREAM_MAX_SIZE, &read_size);
1310                 mapitest_print_retval_fmt(mt, "ReadStream", "(0x%x bytes read)", read_size);
1311                 memcpy(dst_stream + offset, buf, read_size);
1312                 offset += read_size;
1313                 if (retval != MAPI_E_SUCCESS) {
1314                         ret = false;
1315                         break;
1316                 }
1317         } while (read_size || offset != StreamSize);
1318         dst_stream[offset] = '\0';
1319
1320         /* Step 18. Compare streams */
1321         if (!strcmp(stream, dst_stream)) {
1322                 mapitest_print(mt, "* %-35s: [SUCCESS]\n", "Comparison");
1323         } else {
1324                 mapitest_print(mt, "* %-35s: [FAILURE]\n", "Comparison");
1325         }
1326         
1327
1328         /* Step 19. Delete Message */
1329         errno = 0;
1330         id_msgs[0] = mapi_object_get_id(&obj_message);
1331         retval = DeleteMessage(&obj_folder, id_msgs, 1);
1332         mapitest_print_retval(mt, "DeleteMessage");
1333         if (retval != MAPI_E_SUCCESS) {
1334                 ret = false;
1335         }
1336
1337         /* Release */
1338         mapi_object_release(&obj_stream2);
1339         mapi_object_release(&obj_stream);
1340         mapi_object_release(&obj_attach2);
1341         mapi_object_release(&obj_attach);
1342         mapi_object_release(&obj_message);
1343         mapi_object_release(&obj_folder);
1344         mapi_object_release(&obj_store);
1345
1346         talloc_free(stream);
1347         talloc_free(dst_stream);
1348
1349         return ret;
1350 }
1351
1352
1353 /**
1354    \details Test the CopyTo (0x39) operation
1355
1356    This function:
1357    -# Opens the mailbox
1358    -# Creates a test folder
1359    -# Creates a reference email, and sets some properties on it
1360    -# Checks those properties are set correctly
1361    -# Creates a second email, and sets some (different) properties on it
1362    -# Checks those properties on the second folder are set correctly
1363    -# Copies properties from the reference email to the second email (no overwrite)
1364    -# Checks that properties on both emails are correct
1365    -# Copies properties again, but with overwrite
1366    -# Checks that properties on both emails are correct
1367    -# Moves properties from the original email to the second email (no overwrite)
1368    -# Checks that properties on both emails are correct
1369    -# Creates an attachment (with properties) on the reference email
1370    -# Creates an attachment (with different properties) on the target email
1371    -# Copies the properties on the reference email to the target
1372    -# Checks the properties on both attachments are correct
1373    -# Creates another folder
1374    -# Copies properties from the test folder to the new folder
1375    -# Checks that the properties on both folders are correct
1376    -# Deletes both emails and the test folders
1377
1378    \todo It would be useful to test the problem return values
1379
1380    \param mt pointer to the top-level mapitest structure
1381
1382    \return true on success, otherwise false
1383  */
1384 _PUBLIC_ bool mapitest_oxcprpt_CopyTo(struct mapitest *mt)
1385 {
1386         enum MAPISTATUS         retval;
1387         mapi_object_t           obj_store;
1388         mapi_object_t           obj_top_folder;
1389         mapi_id_t               id_top_folder;
1390         mapi_object_t           obj_ref_folder;
1391         mapi_object_t           obj_targ_folder;
1392         mapi_object_t           obj_ref_message;
1393         mapi_object_t           obj_target_message;
1394         mapi_object_t           obj_ref_attach;
1395         mapi_object_t           obj_targ_attach;
1396         const char              *name = NULL;
1397         const char              *subject = NULL;
1398         const char              *dept = NULL;
1399         struct SPropValue       lpProp[3];
1400         struct SPropTagArray    *exclude;
1401         struct SPropTagArray    *SPropTagArray;
1402         struct SPropValue       *lpProps;
1403         uint32_t                cValues;
1404         const char              *targ_name = NULL;
1405         const char              *targ_dept = NULL;
1406         uint16_t                problem_count = 999;
1407         struct PropertyProblem  *problems = NULL;
1408         bool                    result;
1409         bool                    ret = true;
1410
1411         /* Step 1. Logon Private Mailbox */
1412         mapi_object_init(&obj_store);
1413         mapi_object_init(&obj_top_folder);
1414         mapi_object_init(&obj_ref_folder);
1415         mapi_object_init(&obj_targ_folder);
1416         mapi_object_init(&obj_ref_message);
1417         mapi_object_init(&obj_target_message);
1418         mapi_object_init(&obj_ref_attach);
1419         mapi_object_init(&obj_targ_attach);
1420         
1421         retval = OpenMsgStore(mt->session, &obj_store);
1422         mapitest_print_retval(mt, "OpenMsgStore");
1423         if (retval != MAPI_E_SUCCESS) {
1424                 return false;
1425         }
1426         retval = GetDefaultFolder(&obj_store, &id_top_folder, olFolderTopInformationStore);
1427         mapitest_print_retval(mt, "GetDefaultFolder");
1428
1429         retval = OpenFolder(&obj_store, id_top_folder, &obj_top_folder);
1430         mapitest_print_retval(mt, "OpenFolder");
1431         if (retval != MAPI_E_SUCCESS) {
1432                 ret = false;
1433                 goto cleanup;
1434         }
1435
1436         /* Step 2: Create reference folder */
1437         retval = CreateFolder(&obj_top_folder, FOLDER_GENERIC, MT_DIRNAME_TOP, NULL,
1438                               OPEN_IF_EXISTS, &obj_ref_folder);
1439         mapitest_print_retval_fmt(mt, "CreateFolder", "(Create test folder)");
1440         if (retval != MAPI_E_SUCCESS) {
1441                 ret = false;
1442                 goto cleanup;
1443         }
1444         lpProp[0].ulPropTag = PR_CONTAINER_CLASS;
1445         lpProp[0].value.lpszA = "IPF.Note";
1446         retval = SetProps(&obj_ref_folder, lpProp, 1);
1447         mapitest_print_retval(mt, "SetProps");
1448         if (retval != MAPI_E_SUCCESS) {
1449                 ret = false;
1450                 goto cleanup;
1451         }
1452
1453         /* Step 3: Create reference message */
1454         result = mapitest_common_message_create(mt, &obj_ref_folder, &obj_ref_message, MT_MAIL_SUBJECT);
1455         mapitest_print_retval(mt, "mapitest_common_message_create");
1456         if (result != true) {
1457                 ret = false;
1458                 goto cleanup;
1459         }
1460         retval = SaveChangesMessage(&obj_ref_folder, &obj_ref_message, KeepOpenReadWrite);
1461         mapitest_print_retval(mt, "SaveChangesMessage");
1462         if (retval != MAPI_E_SUCCESS) {
1463                 ret = false;
1464                 goto cleanup;
1465         }
1466
1467         name = talloc_asprintf(mt->mem_ctx, "Reference: %s", "display name");
1468         subject = talloc_asprintf(mt->mem_ctx, "Reference: %s", "subject");
1469         dept = talloc_asprintf(mt->mem_ctx, "Reference: %s", "dept");
1470         set_SPropValue_proptag(&lpProp[0], PR_DISPLAY_NAME, (const void *)name);
1471         set_SPropValue_proptag(&lpProp[1], PR_SUBJECT, (const void *)subject);
1472         set_SPropValue_proptag(&lpProp[2], PR_DEPARTMENT_NAME, (const void *)dept);
1473         retval = SetProps(&obj_ref_message, lpProp, 3);
1474         mapitest_print_retval(mt, "SetProps");
1475         if (retval != MAPI_E_SUCCESS) {
1476                 ret = false;
1477                 goto cleanup;
1478         }
1479
1480         /* Step 4: Double check with GetProps */
1481         SPropTagArray = set_SPropTagArray(mt->mem_ctx, 0x3, PR_DISPLAY_NAME, PR_SUBJECT,
1482                                           PR_DEPARTMENT_NAME);
1483         retval = GetProps(&obj_ref_message, SPropTagArray, &lpProps, &cValues);
1484         MAPIFreeBuffer(SPropTagArray);
1485         if (lpProps[0].value.lpszA) {
1486                 if (!strncmp(name, lpProps[0].value.lpszA, strlen(lpProps[0].value.lpszA))) {
1487                         mapitest_print(mt, "* Step 4A - Check: Reference props set - [SUCCESS] (%s)\n",
1488                                        lpProps[0].value.lpszA);
1489                 } else {
1490                         mapitest_print(mt, "* Step 4A - Check: Reference props set [FAILURE] (%s)\n",
1491                                        lpProps[0].value.lpszA);
1492                         ret = false;
1493                         goto cleanup;
1494                 }
1495         }
1496         if (lpProps[1].value.lpszA) {
1497                 if (!strncmp(subject, lpProps[1].value.lpszA, strlen(lpProps[1].value.lpszA))) {
1498                         mapitest_print(mt, "* Step 4B - Check: Reference props set - [SUCCESS] (%s)\n",
1499                                        lpProps[1].value.lpszA);
1500                 } else {
1501                         mapitest_print(mt, "* Step 4B - Check: Reference props set [FAILURE] (%s)\n",
1502                                        lpProps[1].value.lpszA);
1503                         ret = false;
1504                         goto cleanup;
1505                 }
1506         }
1507         if (lpProps[2].value.lpszA) {
1508                 if (!strncmp(dept, lpProps[2].value.lpszA, strlen(lpProps[2].value.lpszA))) {
1509                         mapitest_print(mt, "* Step 4C - Check: Reference props set - [SUCCESS] (%s)\n",
1510                                        lpProps[2].value.lpszA);
1511                 } else {
1512                         mapitest_print(mt, "* Step 4C - Check: Reference props set [FAILURE] (%s)\n",
1513                                        lpProps[2].value.lpszA);
1514                         ret = false;
1515                         goto cleanup;
1516                 }
1517         }
1518
1519         /* Step 5: Create target message */
1520         result = mapitest_common_message_create(mt, &obj_ref_folder, &obj_target_message, MT_MAIL_SUBJECT);
1521         mapitest_print_retval(mt, "mapitest_common_message_create");
1522         if (result != true) {
1523                 ret = false;
1524                 goto cleanup;
1525         }
1526
1527         retval = SaveChangesMessage(&obj_ref_folder, &obj_target_message, KeepOpenReadWrite);
1528         mapitest_print_retval_clean(mt, "5A. SaveChangesMessage", retval);
1529         if (retval != MAPI_E_SUCCESS) {
1530                 ret = false;
1531                 goto cleanup;
1532         }
1533
1534         SPropTagArray = set_SPropTagArray(mt->mem_ctx, 0x1, PR_SUBJECT);
1535         retval = DeleteProps(&obj_target_message, SPropTagArray);
1536         MAPIFreeBuffer(SPropTagArray);
1537         mapitest_print_retval_clean(mt, "5B. DeleteProps - PR_SUBJECT", retval);
1538         
1539         targ_name = talloc_asprintf(mt->mem_ctx, "Target: %s", "display name");
1540         targ_dept = talloc_asprintf(mt->mem_ctx, "Target: %s", "department");
1541         set_SPropValue_proptag(&lpProp[0], PR_DISPLAY_NAME, (const void *)targ_name);
1542         set_SPropValue_proptag(&lpProp[1], PR_DEPARTMENT_NAME, (const void *)targ_dept);
1543         retval = SetProps(&obj_target_message, lpProp, 2);
1544         mapitest_print_retval_clean(mt, "SetProps", retval);
1545         if (retval != MAPI_E_SUCCESS) {
1546                 ret = false;
1547                 goto cleanup;
1548         }
1549
1550         /* Step 6: Double check with GetProps */
1551         SPropTagArray = set_SPropTagArray(mt->mem_ctx, 0x2, PR_DISPLAY_NAME, PR_DEPARTMENT_NAME);
1552         retval = GetProps(&obj_target_message, SPropTagArray, &lpProps, &cValues);
1553         MAPIFreeBuffer(SPropTagArray);
1554         if (lpProps[0].value.lpszA) {
1555                 if (!strncmp(targ_name, lpProps[0].value.lpszA, strlen(lpProps[0].value.lpszA))) {
1556                         mapitest_print(mt, "* Step 6A - Check: Reference props set - [SUCCESS] (%s)\n",
1557                                        lpProps[0].value.lpszA);
1558                 } else {
1559                         mapitest_print(mt, "* Step 6A - Check: Reference props set [FAILURE] (%s)\n",
1560                                        lpProps[0].value.lpszA);
1561                         ret = false;
1562                         goto cleanup;
1563
1564                 }
1565         }
1566         if (lpProps[1].value.lpszA) {
1567                 if (!strncmp(targ_dept, lpProps[1].value.lpszA, strlen(lpProps[1].value.lpszA))) {
1568                         mapitest_print(mt, "* Step 6B - Check: Reference props set - [SUCCESS] (%s)\n",
1569                                        lpProps[1].value.lpszA);
1570                 } else {
1571                         mapitest_print(mt, "* Step 6B - Check: Reference props set [FAILURE] (%s)\n",
1572                                        lpProps[1].value.lpszA);
1573                         ret = false;
1574                         goto cleanup;
1575
1576                 }
1577         }
1578
1579
1580         /* Step 7: Copy properties, no overwrite */
1581         exclude = set_SPropTagArray(mt->mem_ctx, 0x0);
1582         retval = CopyTo(&obj_ref_message, &obj_target_message, exclude, CopyFlagsNoOverwrite,
1583                            &problem_count, &problems);
1584         MAPIFreeBuffer(exclude);
1585         MAPIFreeBuffer(problems);
1586         mapitest_print_retval_fmt(mt, "CopyTo", "(no overwrite)");
1587         if (retval != MAPI_E_SUCCESS) {
1588                 ret = false;
1589                 goto cleanup;
1590         }
1591
1592         /* Step 8: Double check with GetProps */
1593         SPropTagArray = set_SPropTagArray(mt->mem_ctx, 0x2, PR_DISPLAY_NAME, PR_SUBJECT);
1594         retval = GetProps(&obj_ref_message, SPropTagArray, &lpProps, &cValues);
1595         MAPIFreeBuffer(SPropTagArray);
1596         if (lpProps[0].value.lpszA) {
1597                 if (!strncmp(name, lpProps[0].value.lpszA, strlen(lpProps[0].value.lpszA))) {
1598                         mapitest_print(mt, "* Step 8A - Check: Reference props still good - [SUCCESS] (%s)\n",
1599                                        lpProps[0].value.lpszA);
1600                 } else {
1601                         mapitest_print(mt, "* Step 8A - Check: Reference props still good [FAILURE] (%s)\n",
1602                                        lpProps[0].value.lpszA);
1603                         ret = false;
1604                         goto cleanup;
1605                 }
1606         }
1607         if (lpProps[1].value.lpszA) {
1608                 if (!strncmp(subject, lpProps[1].value.lpszA, strlen(lpProps[1].value.lpszA))) {
1609                         mapitest_print(mt, "* Step 8B - Check: Reference props still good - [SUCCESS] (%s)\n",
1610                                        lpProps[1].value.lpszA);
1611                 } else {
1612                         mapitest_print(mt, "* Step 8B - Check: Reference props still good [FAILURE] (%s, %s)\n",
1613                                        subject, lpProps[1].value.lpszA);
1614                         ret = false;
1615                         goto cleanup;
1616                 }
1617         }
1618         SPropTagArray = set_SPropTagArray(mt->mem_ctx, 0x3, PR_DISPLAY_NAME, PR_SUBJECT, PR_DEPARTMENT_NAME);
1619         retval = GetProps(&obj_target_message, SPropTagArray, &lpProps, &cValues);
1620         MAPIFreeBuffer(SPropTagArray);
1621         /* this one shouldn't be overwritten */
1622         if (lpProps[0].value.lpszA) {
1623                 if (!strncmp(targ_name, lpProps[0].value.lpszA, strlen(lpProps[0].value.lpszA))) {
1624                         mapitest_print(mt, "* Step 8C - Check: Reference props copy - [SUCCESS] (%s)\n",
1625                                        lpProps[0].value.lpszA);
1626                 } else {
1627                         mapitest_print(mt, "* Step 8C - Check: Reference props copy [FAILURE] (%s)\n",
1628                                        lpProps[0].value.lpszA);
1629                         ret = false;
1630                         goto cleanup;
1631                 }
1632         }
1633         /* this one should be copied */
1634         if (lpProps[1].value.lpszA) {
1635                 if (!strncmp(subject, lpProps[1].value.lpszA, strlen(lpProps[1].value.lpszA))) {
1636                         mapitest_print(mt, "* Step 8D - Check: Reference props copy - [SUCCESS] (%s)\n",
1637                                        lpProps[1].value.lpszA);
1638                 } else {
1639                         mapitest_print(mt, "* Step 8D - Check: Reference props copy [FAILURE] (%s)\n",
1640                                        lpProps[1].value.lpszA);
1641                         ret = false;
1642                         goto cleanup;
1643                 }
1644         }
1645         /* this one should be unchanged */
1646         if (lpProps[2].value.lpszA) {
1647                 if (!strncmp(targ_dept, lpProps[2].value.lpszA, strlen(lpProps[2].value.lpszA))) {
1648                         mapitest_print(mt, "* Step 8E - Check: Reference props copy - [SUCCESS] (%s)\n",
1649                                        lpProps[2].value.lpszA);
1650                 } else {
1651                         mapitest_print(mt, "* Step 8E - Check: Reference props copy [FAILURE] (%s)\n",
1652                                        lpProps[2].value.lpszA);
1653                         ret = false;
1654                         goto cleanup;
1655                 }
1656         }
1657
1658         /* Step 9: Copy properties, with overwrite */
1659         exclude = set_SPropTagArray(mt->mem_ctx, 0x1, PR_DEPARTMENT_NAME);
1660         retval = CopyTo(&obj_ref_message, &obj_target_message, exclude, 0x0,
1661                         &problem_count, &problems);
1662         MAPIFreeBuffer(exclude);
1663         MAPIFreeBuffer(problems);
1664         mapitest_print_retval_fmt(mt, "CopyTo", "(with overwrite)");
1665         if (retval != MAPI_E_SUCCESS) {
1666                 return false;
1667         }
1668
1669         /* Step 10: Double check with GetProps */
1670         SPropTagArray = set_SPropTagArray(mt->mem_ctx, 0x2, PR_DISPLAY_NAME, PR_SUBJECT);
1671         retval = GetProps(&obj_ref_message, SPropTagArray, &lpProps, &cValues);
1672         MAPIFreeBuffer(SPropTagArray);
1673         if (lpProps[0].value.lpszA) {
1674                 if (!strncmp(name, lpProps[0].value.lpszA, strlen(lpProps[0].value.lpszA))) {
1675                         mapitest_print(mt, "* Step 10A - Check: Reference props still good - [SUCCESS] (%s)\n",
1676                                        lpProps[0].value.lpszA);
1677                 } else {
1678                         mapitest_print(mt, "* Step 10A - Check: Reference props still good [FAILURE] (%s)\n",
1679                                        lpProps[0].value.lpszA);
1680                         ret = false;
1681                         goto cleanup;
1682                 }
1683         }
1684         if (lpProps[1].value.lpszA) {
1685                 if (!strncmp(subject, lpProps[1].value.lpszA, strlen(lpProps[1].value.lpszA))) {
1686                         mapitest_print(mt, "* Step 10B - Check: Reference props still good - [SUCCESS] (%s)\n",
1687                                        lpProps[1].value.lpszA);
1688                 } else {
1689                         mapitest_print(mt, "* Step 10B - Check: Reference props still good [FAILURE] (%s)\n",
1690                                        lpProps[1].value.lpszA);
1691                         ret = false;
1692                         goto cleanup;
1693                 }
1694         }
1695         SPropTagArray = set_SPropTagArray(mt->mem_ctx, 0x3, PR_DISPLAY_NAME, PR_SUBJECT, PR_DEPARTMENT_NAME);
1696         retval = GetProps(&obj_target_message, SPropTagArray, &lpProps, &cValues);
1697         MAPIFreeBuffer(SPropTagArray);
1698         /* this one should now be overwritten */
1699         if (lpProps[0].value.lpszA) {
1700                 if (!strncmp(name, lpProps[0].value.lpszA, strlen(lpProps[0].value.lpszA))) {
1701                         mapitest_print(mt, "* Step 10C - Check: Reference props copy - [SUCCESS] (%s)\n",
1702                                        lpProps[0].value.lpszA);
1703                 } else {
1704                         mapitest_print(mt, "* Step 10C - Check: Reference props copy [FAILURE] (%s)\n",
1705                                        lpProps[0].value.lpszA);
1706                         ret = false;
1707                         goto cleanup;
1708                 }
1709         }
1710         /* this one should be copied */
1711         if (lpProps[1].value.lpszA) {
1712                 if (!strncmp(subject, lpProps[1].value.lpszA, strlen(lpProps[1].value.lpszA))) {
1713                         mapitest_print(mt, "* Step 10D - Check: Reference props copy - [SUCCESS] (%s)\n",
1714                                        lpProps[1].value.lpszA);
1715                 } else {
1716                         mapitest_print(mt, "* Step 10D - Check: Reference props copy [FAILURE] (%s)\n",
1717                                        lpProps[1].value.lpszA);
1718                         ret = false;
1719                         goto cleanup;
1720                 }
1721         }
1722         /* this one should be unchanged */
1723         if (lpProps[2].value.lpszA) {
1724                 if (!strncmp(targ_dept, lpProps[2].value.lpszA, strlen(lpProps[2].value.lpszA))) {
1725                         mapitest_print(mt, "* Step 10E - Check: Reference props copy - [SUCCESS] (%s)\n",
1726                                        lpProps[2].value.lpszA);
1727                 } else {
1728                         mapitest_print(mt, "* Step 10E - Check: Reference props copy [FAILURE] (%s)\n",
1729                                        lpProps[2].value.lpszA);
1730                         ret = false;
1731                         goto cleanup;
1732                 }
1733         }
1734
1735         /* Step 11: Move properties, with overwrite */
1736         exclude = set_SPropTagArray(mt->mem_ctx, 0x0);
1737         retval = CopyTo(&obj_ref_message, &obj_target_message, exclude, CopyFlagsMove,
1738                            &problem_count, &problems);
1739         MAPIFreeBuffer(exclude);
1740         MAPIFreeBuffer(problems);
1741         mapitest_print_retval_clean(mt, "* Step 11 - CopyTo (move)", retval);
1742         if (retval != MAPI_E_SUCCESS) {
1743                 ret = false;
1744                 goto cleanup;
1745         }
1746
1747         /* Step 12: Double check with GetProps */
1748         SPropTagArray = set_SPropTagArray(mt->mem_ctx, 0x2, PR_DISPLAY_NAME, PR_SUBJECT);
1749         retval = GetProps(&obj_ref_message, SPropTagArray, &lpProps, &cValues);
1750         MAPIFreeBuffer(SPropTagArray);
1751         if (cValues == 2) {
1752                 mapitest_print(mt, "* Step 12A - Properties removed [SUCCESS]\n");
1753         } else {
1754                 mapitest_print(mt, "* Step 12A - Properties removed [FAILURE]\n");
1755                 ret = false;
1756                 goto cleanup;
1757         }
1758         SPropTagArray = set_SPropTagArray(mt->mem_ctx, 0x3, PR_DISPLAY_NAME, PR_SUBJECT, PR_DEPARTMENT_NAME);
1759         retval = GetProps(&obj_target_message, SPropTagArray, &lpProps, &cValues);
1760         MAPIFreeBuffer(SPropTagArray);
1761         if (lpProps[0].value.lpszA) {
1762                 if (!strncmp(name, lpProps[0].value.lpszA, strlen(lpProps[0].value.lpszA))) {
1763                         mapitest_print(mt, "* Step 12B - Check: Reference props move - [SUCCESS] (%s)\n",
1764                                        lpProps[0].value.lpszA);
1765                 } else {
1766                         mapitest_print(mt, "* Step 12B - Check: Reference props move [FAILURE] (%s)\n",
1767                                        lpProps[0].value.lpszA);
1768                         ret = false;
1769                         goto cleanup;
1770                 }
1771         }
1772         if (lpProps[1].value.lpszA) {
1773                 if (!strncmp(subject, lpProps[1].value.lpszA, strlen(lpProps[1].value.lpszA))) {
1774                         mapitest_print(mt, "* Step 12C - Check: Reference props move - [SUCCESS] (%s)\n",
1775                                        lpProps[1].value.lpszA);
1776                 } else {
1777                         mapitest_print(mt, "* Step 12C - Check: Reference props move [FAILURE] (%s)\n",
1778                                        lpProps[1].value.lpszA);
1779                         ret = false;
1780                         goto cleanup;
1781                 }
1782         }
1783         if (lpProps[2].value.lpszA) {
1784                 if (!strncmp(dept, lpProps[2].value.lpszA, strlen(lpProps[2].value.lpszA))) {
1785                         mapitest_print(mt, "* Step 12D - Check: Reference props move - [SUCCESS] (%s)\n",
1786                                        lpProps[2].value.lpszA);
1787                 } else {
1788                         mapitest_print(mt, "* Step 12D - Check: Reference props move [FAILURE] (%s)\n",
1789                                        lpProps[2].value.lpszA);
1790                         ret = false;
1791                         goto cleanup;
1792                 }
1793         }
1794
1795         /* Step 13: Create attachment on reference email, and set properties */
1796         retval = CreateAttach(&obj_ref_message, &obj_ref_attach);
1797         mapitest_print_retval(mt, "CreateAttach");
1798         if (retval != MAPI_E_SUCCESS) {
1799                 ret = false;
1800                 goto cleanup;
1801         }
1802         lpProp[0].ulPropTag = PR_ATTACH_METHOD;
1803         lpProp[0].value.l = ATTACH_BY_VALUE;
1804         lpProp[1].ulPropTag = PR_RENDERING_POSITION;
1805         lpProp[1].value.l = 0;
1806         lpProp[2].ulPropTag = PR_ATTACH_FILENAME;
1807         lpProp[2].value.lpszA = MT_MAIL_ATTACH;
1808         retval = SetProps(&obj_ref_attach, lpProp, 3);
1809         mapitest_print_retval(mt, "SetProps");
1810         if (retval != MAPI_E_SUCCESS) {
1811                 ret = false;
1812                 goto cleanup;
1813         }
1814         SaveChangesAttachment(&obj_ref_message, &obj_ref_attach, KeepOpenReadWrite);
1815         mapitest_print_retval(mt, "SaveChangesAttachment");
1816
1817         /* Step 14: Create attachment on target email */
1818         retval = CreateAttach(&obj_target_message, &obj_targ_attach);
1819         mapitest_print_retval(mt, "CreateAttach");
1820         if (retval != MAPI_E_SUCCESS) {
1821                 ret = false;
1822                 goto cleanup;
1823         }
1824         lpProp[0].ulPropTag = PR_ATTACH_METHOD;
1825         lpProp[0].value.l = ATTACH_BY_VALUE;
1826         lpProp[1].ulPropTag = PR_RENDERING_POSITION;
1827         lpProp[1].value.l = 0;
1828         lpProp[2].ulPropTag = PR_ATTACH_FILENAME;
1829         lpProp[2].value.lpszA = MT_MAIL_ATTACH2;
1830         retval = SetProps(&obj_targ_attach, lpProp, 3);
1831         mapitest_print_retval(mt, "SetProps");
1832         if (retval != MAPI_E_SUCCESS) {
1833                 ret = false;
1834                 goto cleanup;
1835         }
1836         retval = SaveChangesAttachment(&obj_target_message, &obj_targ_attach, KeepOpenReadWrite);
1837         mapitest_print_retval_clean(mt, "SaveChangesAttachment", retval);
1838
1839         /* Step 15: Copy props from reference email attachment to target email attachment */
1840         exclude = set_SPropTagArray(mt->mem_ctx, 0x0);
1841         retval = CopyTo(&obj_ref_attach, &obj_targ_attach, exclude, 0x0, &problem_count, &problems);
1842         MAPIFreeBuffer(exclude);
1843         MAPIFreeBuffer(problems);
1844         mapitest_print_retval_fmt(mt, "CopyTo", "(attachments)");
1845         if (retval != MAPI_E_SUCCESS) {
1846                 ret = false;
1847                 goto cleanup;
1848         }
1849         retval = SaveChangesAttachment(&obj_target_message, &obj_targ_attach, KeepOpenReadWrite);
1850         mapitest_print_retval_clean(mt, "SaveChangesAttachment 2", retval);
1851
1852         /* Step 16: Check properties on both attachments are correct */
1853         SPropTagArray = set_SPropTagArray(mt->mem_ctx, 0x1, PR_ATTACH_FILENAME);
1854         retval = GetProps(&obj_ref_attach, SPropTagArray, &lpProps, &cValues);
1855         mapitest_print_retval(mt, "GetProps");
1856         if (retval != MAPI_E_SUCCESS) {
1857                 ret = false;
1858                 goto cleanup;
1859         }
1860         MAPIFreeBuffer(SPropTagArray);
1861         if (lpProps[0].value.lpszA) {
1862                 if (!strncmp(MT_MAIL_ATTACH, lpProps[0].value.lpszA, strlen(lpProps[0].value.lpszA))) {
1863                         mapitest_print(mt, "* Step 16B - Check: Reference attachment props - [SUCCESS] (%s)\n",
1864                                        lpProps[0].value.lpszA);
1865                 } else {
1866                         mapitest_print(mt, "* Step 16B - Check: Reference attachment props [FAILURE] (%s, %s)\n",
1867                                        lpProps[0].value.lpszA, MT_MAIL_ATTACH);
1868                         ret = false;
1869                         goto cleanup;
1870                 }
1871         }       
1872         SPropTagArray = set_SPropTagArray(mt->mem_ctx, 0x1, PR_ATTACH_FILENAME);
1873         retval = GetProps(&obj_targ_attach, SPropTagArray, &lpProps, &cValues);
1874         mapitest_print_retval(mt, "GetProps");
1875         if (retval != MAPI_E_SUCCESS) {
1876                 ret = false;
1877                 goto cleanup;
1878         }
1879         MAPIFreeBuffer(SPropTagArray);
1880         if (lpProps[0].value.lpszA) {
1881                 if (!strncmp(MT_MAIL_ATTACH, lpProps[0].value.lpszA, strlen(lpProps[0].value.lpszA))) {
1882                         mapitest_print(mt, "* Step 16D - Check: Target attachment props - [SUCCESS] (%s)\n",
1883                                        lpProps[0].value.lpszA);
1884                 } else {
1885                         mapitest_print(mt, "* Step 16D - Check: Target attachment props [FAILURE] (%s)\n",
1886                                        lpProps[0].value.lpszA);
1887                         ret = false;
1888                         goto cleanup;
1889                 }
1890         }       
1891
1892         /* Create another folder */
1893         retval = CreateFolder(&obj_top_folder, FOLDER_GENERIC, "[MT] Target Folder", NULL,
1894                               OPEN_IF_EXISTS, &obj_targ_folder);
1895         mapitest_print_retval(mt, "CreateFolder");
1896         if (retval != MAPI_E_SUCCESS) {
1897                 ret = false;
1898                 goto cleanup;
1899         }
1900         lpProp[0].ulPropTag = PR_CONTAINER_CLASS;
1901         lpProp[0].value.lpszA = "IPF.Journal";
1902         retval = SetProps(&obj_targ_folder, lpProp, 1);
1903         mapitest_print_retval(mt, "SetProps");
1904         if (retval != MAPI_E_SUCCESS) {
1905                 ret = false;
1906                 goto cleanup;
1907         }
1908
1909         /* Copy properties from the test folder to the new folder */
1910         exclude = set_SPropTagArray(mt->mem_ctx, 0x1, PR_DISPLAY_NAME);
1911         retval = CopyTo(&obj_ref_folder, &obj_targ_folder, exclude, 0x0, &problem_count, &problems);
1912         MAPIFreeBuffer(exclude);
1913         MAPIFreeBuffer(problems);
1914         mapitest_print_retval_fmt(mt, "CopyTo", "(folder)");
1915         if (retval != MAPI_E_SUCCESS) {
1916                 ret = false;
1917                 goto cleanup;
1918         }       
1919
1920         /* Check that the properties on both folders are correct */
1921         SPropTagArray = set_SPropTagArray(mt->mem_ctx, 0x2, PR_DISPLAY_NAME, PR_CONTAINER_CLASS);
1922         retval = GetProps(&obj_ref_folder, SPropTagArray, &lpProps, &cValues);
1923         mapitest_print_retval(mt, "GetProps");
1924         if (retval != MAPI_E_SUCCESS) {
1925                 ret = false;
1926                 goto cleanup;
1927         }
1928         MAPIFreeBuffer(SPropTagArray);
1929         if (lpProps[0].value.lpszA) {
1930                 if (!strncmp(MT_DIRNAME_TOP, lpProps[0].value.lpszA, strlen(lpProps[0].value.lpszA))) {
1931                         mapitest_print(mt, "* Step 19B - Check: Reference folder props - [SUCCESS] (%s)\n",
1932                                        lpProps[0].value.lpszA);
1933                 } else {
1934                         mapitest_print(mt, "* Step 19B - Check: Reference folder props [FAILURE] (%s)\n",
1935                                        lpProps[0].value.lpszA);
1936                         ret = false;
1937                         goto cleanup;
1938                 }
1939         }       
1940         if (lpProps[1].value.lpszA) {
1941                 if (!strncmp("IPF.Note", lpProps[1].value.lpszA, strlen(lpProps[1].value.lpszA))) {
1942                         mapitest_print(mt, "* Step 19C - Check: Reference folder props - [SUCCESS] (%s)\n",
1943                                        lpProps[1].value.lpszA);
1944                 } else {
1945                         mapitest_print(mt, "* Step 19C - Check: Reference folder props [FAILURE] (%s)\n",
1946                                        lpProps[1].value.lpszA);
1947                         ret = false;
1948                         goto cleanup;
1949                 }
1950         }
1951         SPropTagArray = set_SPropTagArray(mt->mem_ctx, 0x2, PR_DISPLAY_NAME, PR_CONTAINER_CLASS);
1952         retval = GetProps(&obj_targ_folder, SPropTagArray, &lpProps, &cValues);
1953         mapitest_print_retval(mt, "GetProps");
1954         if (retval != MAPI_E_SUCCESS) {
1955                 ret = false;
1956                 goto cleanup;
1957         }
1958         MAPIFreeBuffer(SPropTagArray);
1959         if (lpProps[0].value.lpszA) {
1960                 if (!strncmp("[MT] Target Folder", lpProps[0].value.lpszA, strlen(lpProps[0].value.lpszA))) {
1961                         mapitest_print(mt, "* Step 19E - Check: Target folder props - [SUCCESS] (%s)\n",
1962                                        lpProps[0].value.lpszA);
1963                 } else {
1964                         mapitest_print(mt, "* Step 19E - Check: Target folder props [FAILURE] (%s)\n",
1965                                        lpProps[0].value.lpszA);
1966                         ret = false;
1967                         goto cleanup;
1968                 }
1969         }       
1970         if (lpProps[1].value.lpszA) {
1971                 if (!strncmp("IPF.Note", lpProps[1].value.lpszA, strlen(lpProps[1].value.lpszA))) {
1972                         mapitest_print(mt, "* Step 19F - Check: Target folder props - [SUCCESS] (%s)\n",
1973                                        lpProps[1].value.lpszA);
1974                 } else {
1975                         mapitest_print(mt, "* Step 19F - Check: Target folder props [FAILURE] (%s)\n",
1976                                        lpProps[1].value.lpszA);
1977                         ret = false;
1978                         goto cleanup;
1979                 }
1980         }       
1981
1982
1983  cleanup:
1984         /* Cleanup reference strings */
1985         MAPIFreeBuffer((void *)subject);
1986         MAPIFreeBuffer((void *)name);
1987         MAPIFreeBuffer((void *)targ_name);
1988         MAPIFreeBuffer((void *)targ_dept);
1989
1990         /* Cleanup folders */
1991         retval = DeleteFolder(&obj_top_folder, mapi_object_get_id(&obj_targ_folder),
1992                               DEL_FOLDERS | DEL_MESSAGES | DELETE_HARD_DELETE, NULL);
1993         mapitest_print_retval(mt, "DeleteFolder");
1994         retval = DeleteFolder(&obj_top_folder, mapi_object_get_id(&obj_ref_folder),
1995                               DEL_FOLDERS | DEL_MESSAGES | DELETE_HARD_DELETE, NULL);
1996         mapitest_print_retval(mt, "DeleteFolder");
1997
1998         /* Release */
1999         mapi_object_release(&obj_targ_attach);
2000         mapi_object_release(&obj_ref_attach);
2001         mapi_object_release(&obj_ref_message);
2002         mapi_object_release(&obj_ref_folder);
2003         mapi_object_release(&obj_top_folder);
2004         mapi_object_release(&obj_store);
2005
2006         return ret;
2007 }
2008
2009 #define NAMEDPROP_NAME "mapitest_namedprop"
2010 #define NAMEDPROP_IDNUM 0xDB
2011
2012 /**
2013    \details Test the GetPropertyIdsFromNames (0x56),
2014    GetNamesFromPropertyIds (0x55) and QueryNamesFromIDs (0x5f) 
2015    operations
2016
2017    This function:
2018    -# Logs into the server
2019    -# Create a test folder and test message
2020    -# Creates one MNID_ID property
2021    -# Creates one MNID_STRING property
2022    -# Builds a table of Name, ID pairs using QueryNamesFromIDs()
2023    -# Iterates over names, and calls GetIDsFromNames() on each name
2024    -# Iterates over IDs, and calls GetNamesFromIDs() on each ID
2025    -# Cleans up
2026
2027    \param mt pointer to the top-level mapitest structure
2028
2029    \return true on success, otherwise false
2030  */
2031 _PUBLIC_ bool mapitest_oxcprpt_NameId(struct mapitest *mt)
2032 {
2033         enum MAPISTATUS         retval;
2034         mapi_object_t           obj_store;
2035         mapi_object_t           obj_top_folder;
2036         mapi_id_t               id_top_folder;
2037         mapi_object_t           obj_ref_folder;
2038         mapi_object_t           obj_ref_message;
2039         struct mapi_nameid      *nameid;
2040         struct mapi_nameid      *nameid2;
2041         struct MAPINAMEID       checknameid;
2042         struct SPropTagArray    *SPropTagArray;
2043         uint32_t                propID;
2044         uint16_t                *propIDs;
2045         bool                    ret = true;
2046         int                     i;
2047         bool                    result;
2048
2049         /* Log into the server */
2050         mapi_object_init(&obj_store);
2051         mapi_object_init(&obj_top_folder);
2052         mapi_object_init(&obj_ref_folder);
2053         mapi_object_init(&obj_ref_message);
2054
2055         retval = OpenMsgStore(mt->session, &obj_store);
2056         mapitest_print_retval(mt, "OpenMsgStore");
2057         if (retval != MAPI_E_SUCCESS) {
2058                 return false;
2059         }
2060
2061         retval = GetDefaultFolder(&obj_store, &id_top_folder, olFolderTopInformationStore);
2062         mapitest_print_retval(mt, "GetDefaultFolder");
2063         if (retval != MAPI_E_SUCCESS) {
2064                 ret = false;
2065                 goto cleanup;
2066         }
2067
2068         retval = OpenFolder(&obj_store, id_top_folder, &obj_top_folder);
2069         mapitest_print_retval(mt, "OpenFolder");
2070         if (retval != MAPI_E_SUCCESS) {
2071                 ret = false;
2072                 goto cleanup;
2073         }
2074
2075         /* Step 2: Create test folder */
2076         retval = CreateFolder(&obj_top_folder, FOLDER_GENERIC, MT_DIRNAME_TOP, NULL,
2077                      OPEN_IF_EXISTS, &obj_ref_folder);
2078         mapitest_print_retval(mt, "CreateFolder");
2079         if (retval != MAPI_E_SUCCESS) {
2080                 ret = false;
2081                 goto cleanup;
2082         }
2083
2084         result = mapitest_common_message_create(mt, &obj_ref_folder, &obj_ref_message, MT_MAIL_SUBJECT);
2085         if (result != true) {
2086                 mapitest_print_retval(mt, "mapitest_common_message_create failed");
2087                 ret = false;
2088                 goto cleanup;
2089         }
2090         retval = SaveChangesMessage(&obj_ref_folder, &obj_ref_message, KeepOpenReadWrite);
2091         mapitest_print_retval(mt, "SaveChangesMessage");
2092         if (retval != MAPI_E_SUCCESS) {
2093                 ret = false;
2094                 goto cleanup;
2095         }
2096
2097         /* Step 3: Create and Retrieve one MNID_ID property */
2098
2099         /* Build the list of named properties we want to create */
2100         nameid = mapi_nameid_new(mt->mem_ctx);
2101         mapi_nameid_custom_lid_add(nameid, NAMEDPROP_IDNUM, PT_STRING8, PS_PUBLIC_STRINGS);
2102
2103         /* GetIDsFromNames and map property types */
2104         SPropTagArray = talloc_zero(mt->mem_ctx, struct SPropTagArray);
2105         retval = GetIDsFromNames(&obj_ref_message, nameid->count, 
2106                                  nameid->nameid, MAPI_CREATE, &SPropTagArray);
2107         mapitest_print_retval(mt, "GetIDsFromNames");
2108         if (retval != MAPI_E_SUCCESS) {
2109                 ret = false;
2110                 MAPIFreeBuffer(nameid);
2111                 goto cleanup;
2112         }
2113
2114         mapi_nameid_SPropTagArray(nameid, SPropTagArray);
2115         MAPIFreeBuffer(nameid);
2116         
2117         propID = SPropTagArray->aulPropTag[0];
2118         MAPIFreeBuffer(SPropTagArray);
2119
2120         nameid = mapi_nameid_new(mt->mem_ctx);
2121         retval = GetNamesFromIDs(&obj_ref_message, propID, &nameid->count, &nameid->nameid);
2122         mapitest_print_retval(mt, "GetNamesFromIDs");
2123         if (retval != MAPI_E_SUCCESS) {
2124                 MAPIFreeBuffer(nameid);
2125                 ret = false;
2126                 goto cleanup;
2127         }
2128
2129         if ((nameid->nameid[0].ulKind != MNID_ID) || (nameid->nameid[0].kind.lid != NAMEDPROP_IDNUM)) {
2130                 errno = MAPI_E_RESERVED;
2131                 mapitest_print_retval_fmt(mt, "GetNamesFromIDs", 
2132                                           "Unexpected result: ulKind: %x mapped to 0x%.4x", 
2133                                           nameid->nameid[0].ulKind, nameid->nameid[0].kind.lid);
2134                 ret = false;
2135                 goto cleanup;
2136         }
2137
2138         MAPIFreeBuffer(nameid);
2139
2140         /* Step 4: Create one MNID_STRING property */
2141         nameid = mapi_nameid_new(mt->mem_ctx);
2142         SPropTagArray = talloc_zero(mt->mem_ctx, struct SPropTagArray);
2143
2144         mapi_nameid_custom_string_add(nameid, NAMEDPROP_NAME, PT_STRING8, PS_PUBLIC_STRINGS);
2145         retval = GetIDsFromNames(&obj_ref_folder, nameid->count, nameid->nameid, MAPI_CREATE, &SPropTagArray);
2146         mapitest_print_retval(mt, "GetIDsFromNames");
2147         if (retval != MAPI_E_SUCCESS) {
2148                 MAPIFreeBuffer(nameid);
2149                 ret = false;
2150                 goto cleanup;
2151         }
2152
2153         mapi_nameid_SPropTagArray(nameid, SPropTagArray);
2154         MAPIFreeBuffer(nameid);
2155
2156         propID = SPropTagArray->aulPropTag[0];
2157         MAPIFreeBuffer(SPropTagArray);
2158
2159         /* Builds an array of Name,ID pairs using QueryNamesFromIDs() */
2160         nameid = mapi_nameid_new(mt->mem_ctx);
2161         retval = QueryNamedProperties(&obj_ref_message, 0x1, NULL, &nameid->count, &propIDs, &nameid->nameid);
2162         nameid->nameid = talloc_steal((TALLOC_CTX *)nameid, nameid->nameid);
2163         mapitest_print_retval(mt, "QueryNamedProperties");
2164         if (retval != MAPI_E_SUCCESS) {
2165                 MAPIFreeBuffer(nameid);
2166                 talloc_free(propIDs);
2167                 ret = false;
2168                 goto cleanup;
2169         }
2170
2171         /* Iterate over names and call GetIDsFromNames() on each name */
2172         for (i = 0; i < nameid->count; i++) {
2173                 checknameid.lpguid = nameid->nameid[i].lpguid;
2174                 checknameid.ulKind = nameid->nameid[i].ulKind;
2175
2176                 switch (nameid->nameid[i].ulKind) {
2177                 case MNID_ID:
2178                         checknameid.kind.lid = nameid->nameid[i].kind.lid;
2179                         break;
2180                 case MNID_STRING:
2181                         checknameid.kind.lpwstr.Name = nameid->nameid[i].kind.lpwstr.Name;
2182                         checknameid.kind.lpwstr.NameSize = nameid->nameid[i].kind.lpwstr.NameSize;
2183                         break;
2184                 }
2185
2186                 SPropTagArray = talloc_zero(mt->mem_ctx, struct SPropTagArray);
2187                 retval = GetIDsFromNames(&obj_ref_folder, 1, &checknameid, 0, &SPropTagArray);
2188                 if (retval != MAPI_E_SUCCESS) {
2189                         mapitest_print_retval(mt, "GetIDsFromNames");
2190                         MAPIFreeBuffer(nameid);
2191                         MAPIFreeBuffer(SPropTagArray);
2192                         ret = false;
2193                         goto cleanup;
2194                 }
2195
2196                 /* check we got the right number of IDs */
2197                 if (SPropTagArray->cValues != 1) {
2198                         errno = MAPI_E_RESERVED;
2199                         mapitest_print_retval_fmt(mt, "GetIDsFromNames", "Unexpected ID count (%i)", SPropTagArray->cValues);
2200                         MAPIFreeBuffer(nameid);
2201                         MAPIFreeBuffer(SPropTagArray);
2202                         ret = false;
2203                         goto cleanup;
2204                 }
2205
2206                 /* check if the ID is the one we expected */
2207                 if (SPropTagArray->aulPropTag[0] != (propIDs[i] << 16)) {
2208                         errno = MAPI_E_RESERVED;
2209                         mapitest_print_retval_fmt(mt, "GetIDsFromNames", "Unexpected ID (0x%x, expected 0x%x)",
2210                                                   SPropTagArray->aulPropTag[0], (propIDs[i] << 16));
2211                         MAPIFreeBuffer(nameid);
2212                         MAPIFreeBuffer(SPropTagArray);
2213                         ret = false;
2214                         goto cleanup;
2215                 }
2216                 MAPIFreeBuffer(SPropTagArray);
2217         }
2218         mapitest_print(mt, "* Step 6: All IDs matched [SUCCESS]\n");
2219
2220         /* Iterates over IDs, and call GetNamesFromIDs() on each ID */
2221         for (i = 0; i < nameid->count; i++) {
2222                 nameid2 = mapi_nameid_new(mt->mem_ctx);
2223                 retval = GetNamesFromIDs(&obj_ref_folder, (propIDs[i] << 16), &nameid2->count, &nameid2->nameid);
2224                 if (retval != MAPI_E_SUCCESS) {
2225                         mapitest_print_retval(mt, "GetNamesFromIDs");
2226                         MAPIFreeBuffer(nameid2);
2227                         ret = false;
2228                         goto cleanup;
2229                 }
2230
2231                 /* Check we got the right number of names */
2232                 if (nameid2->count != 1) {
2233                         mapitest_print_retval_fmt(mt, "GetNamesFromIDs", "Unexpected name count (%i)", nameid2->count);
2234                         MAPIFreeBuffer(nameid);
2235                         MAPIFreeBuffer(nameid2);
2236                         ret = false;
2237                         goto cleanup;
2238                 }
2239
2240                 /* Check we got the right kind of name */
2241                 if (nameid2->nameid[0].ulKind != nameid->nameid[i].ulKind) {
2242                         mapitest_print_retval_fmt(mt, "GetIDsFromNames", "Unexpected kind (0x%x, expected 0x%x)",
2243                                                   nameid2->nameid[0].ulKind, nameid->nameid[i].ulKind);
2244                         MAPIFreeBuffer(nameid);
2245                         MAPIFreeBuffer(nameid2);
2246                         ret = false;
2247                         goto cleanup;
2248                 }
2249
2250                 switch (nameid->nameid[i].ulKind) {
2251                 case MNID_ID:
2252                         if (nameid2->nameid[0].kind.lid != nameid->nameid[i].kind.lid) {
2253                                 mapitest_print_retval_fmt(mt, "GetIDsFromNames", "Unexpected hex name (0x%x, expected 0x%x)",
2254                                                           nameid2->nameid[0].kind.lid, nameid->nameid[i].kind.lid);
2255                                 MAPIFreeBuffer(nameid);
2256                                 MAPIFreeBuffer(nameid2);
2257                                 ret = false;
2258                                 goto cleanup;
2259                         }
2260                         break;
2261                 case MNID_STRING:
2262                         if (nameid2->nameid[0].kind.lpwstr.NameSize != nameid->nameid[i].kind.lpwstr.NameSize) {
2263                                 mapitest_print_retval_fmt(mt, "GetIDsFromNames", "Unexpected name length (0x%x, expected 0x%x)",
2264                                                           nameid2->nameid[0].kind.lpwstr.NameSize, 
2265                                                           nameid->nameid[i].kind.lpwstr.NameSize);
2266                                 MAPIFreeBuffer(nameid);
2267                                 MAPIFreeBuffer(nameid2);
2268                                 ret = false;
2269                                 goto cleanup;
2270                         }
2271                         if (strncmp(nameid2->nameid[0].kind.lpwstr.Name, nameid->nameid[i].kind.lpwstr.Name, nameid->nameid[i].kind.lpwstr.NameSize) != 0) {
2272                                 mapitest_print_retval_fmt(mt, "GetIDsFromNames", "Unexpected name (%s, expected %s)",
2273                                                           nameid2->nameid[0].kind.lpwstr.Name, 
2274                                                           nameid->nameid[i].kind.lpwstr.Name);
2275                                 MAPIFreeBuffer(nameid);
2276                                 MAPIFreeBuffer(nameid2);
2277                                 ret = false;
2278                                 goto cleanup;                           
2279                         }
2280                         break;
2281                 }
2282
2283                 MAPIFreeBuffer(nameid2);
2284         }               
2285         
2286         MAPIFreeBuffer(nameid);
2287         MAPIFreeBuffer(propIDs);
2288
2289  cleanup:
2290         errno = 0;
2291         /* Clean up */
2292         DeleteFolder(&obj_top_folder, mapi_object_get_id(&obj_ref_folder),
2293                      DEL_FOLDERS | DEL_MESSAGES | DELETE_HARD_DELETE, NULL);
2294         mapitest_print_retval(mt, "DeleteFolder");
2295
2296         /* Release */
2297         mapi_object_release(&obj_ref_message);
2298         mapi_object_release(&obj_ref_folder);
2299         mapi_object_release(&obj_top_folder);
2300         mapi_object_release(&obj_store);
2301
2302         return ret;
2303 }
2304
2305 /**
2306    \details Test the GetPropertyIdsFromNames (0x56) and
2307    GetNamesFromPropertyIds (0x55) operations for the special
2308    case of the PS_MAPI namespace
2309
2310    This function:
2311    -# Logs into the server
2312    -# Gets a property ID for a known property name
2313    -# Gets a property name for a known property ID
2314    -# Cleans up
2315
2316    Refer to MS-OXPROPS for the list of properties
2317
2318    \param mt pointer to the top-level mapitest structure
2319
2320    \return true on success, otherwise false
2321  */
2322 _PUBLIC_ bool mapitest_oxcprpt_NameId_PSMAPI(struct mapitest *mt)
2323 {       enum MAPISTATUS         retval;
2324         mapi_object_t           obj_store;
2325         struct mapi_nameid      *nameid;
2326         struct SPropTagArray    *SPropTagArray;
2327         bool                    ret = true;
2328
2329         /* Log into the server */
2330         mapi_object_init(&obj_store);
2331
2332         retval = OpenMsgStore(mt->session, &obj_store);
2333         mapitest_print_retval_clean(mt, "OpenMsgStore", retval);
2334         if (retval != MAPI_E_SUCCESS) {
2335                 ret = false;
2336                 goto cleanup;
2337         }
2338
2339         /* Build the list of named properties we want to get */
2340         nameid = mapi_nameid_new(mt->mem_ctx);
2341         mapi_nameid_custom_lid_add(nameid, (PR_ACCESS>>16), PT_LONG, PS_MAPI); // 0x0FF4
2342         mapi_nameid_custom_lid_add(nameid, (PR_ATTACHMENT_HIDDEN>>16), PT_BOOLEAN, PS_MAPI);
2343
2344         /* GetIDsFromNames and map property types */
2345         SPropTagArray = talloc_zero(mt->mem_ctx, struct SPropTagArray);
2346         retval = GetIDsFromNames(&obj_store, nameid->count, 
2347                                  nameid->nameid, 0, &SPropTagArray);
2348         mapitest_print_retval_clean(mt, "GetIDsFromNames", retval);
2349         if (retval != MAPI_E_SUCCESS) {
2350                 ret = false;
2351                 MAPIFreeBuffer(nameid);
2352                 goto cleanup;
2353         }
2354
2355         mapi_nameid_SPropTagArray(nameid, SPropTagArray);
2356         MAPIFreeBuffer(nameid);
2357         
2358         if (SPropTagArray->aulPropTag[0] == PR_ACCESS) {
2359                 mapitest_print(mt, "Comparison [0] matched\n");
2360         } else {
2361                 mapitest_print(mt, "Comparison [0] failed : 0x%08x\n", SPropTagArray->aulPropTag[0]);
2362         }
2363         if (SPropTagArray->aulPropTag[1] == PR_ATTACHMENT_HIDDEN) {
2364                 mapitest_print(mt, "Comparison [1] matched\n");
2365         } else {
2366                 mapitest_print(mt, "Comparison [1] failed : 0x%08x\n", SPropTagArray->aulPropTag[1]);
2367         }
2368         MAPIFreeBuffer(SPropTagArray);
2369
2370         nameid = mapi_nameid_new(mt->mem_ctx);
2371         retval = GetNamesFromIDs(&obj_store, PR_ATTACHMENT_HIDDEN, &nameid->count, &nameid->nameid);
2372         mapitest_print_retval_clean(mt, "GetNamesFromIDs", retval);
2373         if (retval != MAPI_E_SUCCESS) {
2374                 MAPIFreeBuffer(nameid);
2375                 ret = false;
2376                 goto cleanup;
2377         }
2378         
2379         if (nameid->count != 1) {
2380                 mapitest_print(mt, "Unexpected count from GetNamesFromIDs: %i", nameid->count);
2381                 MAPIFreeBuffer(nameid);
2382                 ret = false;
2383                 goto cleanup;
2384         }
2385         if (nameid->nameid[0].ulKind != MNID_ID) {
2386                 mapitest_print(mt, "Unexpected kind from GetNamesFromIDs: %i", nameid->nameid[0].ulKind);
2387                 MAPIFreeBuffer(nameid);
2388                 ret = false;
2389                 goto cleanup;
2390         }
2391         if (nameid->nameid[0].kind.lid == (PR_ATTACHMENT_HIDDEN >> 16)) {
2392                 mapitest_print(mt, "Comparision of values matches\n");
2393         } else {
2394                 mapitest_print(mt, "Comparison of values mismatch (nameid->lid: 0x%04x)\n", nameid->nameid[0].kind.lid); 
2395         }
2396
2397 cleanup:
2398         mapi_object_release(&obj_store);
2399         return ret;
2400 }
2401 /**
2402    \details Test the SetPropertiesNoReplicate (0x79) and
2403     DeletePropertiesNoReplicate (0x7a) operations
2404
2405    This function:
2406    -# Opens the mailbox
2407    -# Create a test folder
2408    -# Sets some properties on the test folder
2409    -# Delete properties from the test folder
2410    -# Deletes the test folder
2411
2412    \todo It would be useful to test the problem return values
2413
2414    \param mt pointer to the top-level mapitest structure
2415
2416    \return true on success, otherwise false
2417  */
2418 _PUBLIC_ bool mapitest_oxcprpt_NoReplicate(struct mapitest *mt)
2419 {
2420         enum MAPISTATUS         retval;
2421         mapi_object_t           obj_store;
2422         mapi_object_t           obj_top_folder;
2423         mapi_id_t               id_top_folder;
2424         mapi_object_t           obj_ref_folder;
2425         const char              *name = NULL;
2426         const char              *comment = NULL;
2427         struct SPropValue       lpProp[3];
2428         struct SPropTagArray    *SPropTagArray;
2429         struct SPropValue       *lpProps;
2430         uint32_t                cValues;
2431         bool                    ret = true;
2432
2433         /* Step 1. Logon Private Mailbox */
2434         mapi_object_init(&obj_store);
2435         mapi_object_init(&obj_top_folder);
2436         mapi_object_init(&obj_ref_folder);
2437
2438         retval = OpenMsgStore(mt->session, &obj_store);
2439         mapitest_print_retval_step_fmt(mt, "1.", "OpenMsgStore", "(%s)", "Logon Private Mailbox");
2440         if (retval != MAPI_E_SUCCESS) {
2441                 ret = false;
2442                 goto cleanup;
2443         }
2444
2445         retval = GetDefaultFolder(&obj_store, &id_top_folder, olFolderTopInformationStore);
2446         if (retval != MAPI_E_SUCCESS) {
2447                 ret = false;
2448                 goto cleanup;
2449         }
2450         retval = OpenFolder(&obj_store, id_top_folder, &obj_top_folder);
2451         if (retval != MAPI_E_SUCCESS) {
2452                 ret = false;
2453                 goto cleanup;
2454         }
2455
2456         /* Step 2: Create test folder */
2457         retval = CreateFolder(&obj_top_folder, FOLDER_GENERIC, MT_DIRNAME_TOP, NULL,
2458                               OPEN_IF_EXISTS, &obj_ref_folder);
2459         mapitest_print_retval_step_fmt(mt, "2.", "CreateFolder", "(%s)", "Create the test folder");
2460         if (retval != MAPI_E_SUCCESS) {
2461                 ret = false;
2462                 goto cleanup;
2463         }
2464
2465         /* Step 3: Set properties on the test folder */
2466         name = talloc_asprintf(mt->mem_ctx, "Reference: %s", "new name");
2467         comment = talloc_asprintf(mt->mem_ctx, "Reference: %s", "the folder comment");
2468         set_SPropValue_proptag(&lpProp[0], PR_DISPLAY_NAME, (const void *)name);
2469         set_SPropValue_proptag(&lpProp[1], PR_COMMENT, (const void *)comment);
2470         retval = SetPropertiesNoReplicate(&obj_ref_folder, lpProp, 2);
2471         mapitest_print_retval_step_fmt(mt, "3.", "SetProps", "(%s)", "Set folder properties");
2472         if (retval != MAPI_E_SUCCESS) {
2473                 ret = false;
2474                 goto cleanup;
2475         }
2476
2477         /* Step 4: Double check with GetProps */
2478         SPropTagArray = set_SPropTagArray(mt->mem_ctx, 0x2, PR_DISPLAY_NAME, PR_COMMENT);
2479         retval = GetProps(&obj_ref_folder, SPropTagArray, &lpProps, &cValues);
2480         MAPIFreeBuffer(SPropTagArray);
2481         if (lpProps[0].value.lpszA) {
2482                 if (!strncmp(name, lpProps[0].value.lpszA, strlen(lpProps[0].value.lpszA))) {
2483                         mapitest_print(mt, "* Step 4.1. - Check: Reference props set - [SUCCESS] (%s)\n",
2484                                        lpProps[0].value.lpszA);
2485                 } else {
2486                         mapitest_print(mt, "* Step 4.1. - Check: Reference props set [FAILURE] (%s)\n",
2487                                        lpProps[0].value.lpszA);
2488                         ret = false;
2489                         goto cleanup;
2490                 }
2491         }
2492         if (lpProps[1].value.lpszA) {
2493                 if (!strncmp(comment, lpProps[1].value.lpszA, strlen(lpProps[1].value.lpszA))) {
2494                         mapitest_print(mt, "* Step 4.2. - Check: Reference props set - [SUCCESS] (%s)\n",
2495                                        lpProps[1].value.lpszA);
2496                 } else {
2497                         mapitest_print(mt, "* Step 4.2. - Check: Reference props set [FAILURE] (%s)\n",
2498                                        lpProps[1].value.lpszA);
2499                         ret = false;
2500                         goto cleanup;
2501                 }
2502         }
2503
2504         /* Step 5. Delete Properties */
2505         SPropTagArray = set_SPropTagArray(mt->mem_ctx, 0x1, PR_COMMENT);
2506         retval = DeletePropertiesNoReplicate(&obj_ref_folder, SPropTagArray);
2507         MAPIFreeBuffer(SPropTagArray);
2508         mapitest_print_retval_step_fmt(mt, "5.", "DeletePropertiesNoReplicate", "PR_COMMENT");
2509
2510         /* Step 6. Double check with GetProps */
2511         SPropTagArray = set_SPropTagArray(mt->mem_ctx, 0x1, PR_COMMENT);
2512         retval = GetProps(&obj_ref_folder, SPropTagArray, &lpProps, &cValues);
2513         MAPIFreeBuffer(SPropTagArray);
2514         if (get_SPropValue(lpProps, PR_COMMENT) == NULL) {
2515                 mapitest_print(mt, "* Step 6.1. - GetProps verifier [SUCCESS]\n");
2516         } else {
2517                 mapitest_print(mt, "* Step 6.1. - GetProps verifier [FAILURE]:\n");
2518         }
2519
2520         /* Cleanup and release */
2521 cleanup:
2522         retval = DeleteFolder(&obj_top_folder, mapi_object_get_id(&obj_ref_folder),
2523                               DEL_FOLDERS | DEL_MESSAGES | DELETE_HARD_DELETE, NULL);
2524         mapitest_print_retval_step(mt, "7.", "DeleteFolder", retval);
2525         mapi_object_release(&obj_ref_folder);
2526         mapi_object_release(&obj_top_folder);
2527         mapi_object_release(&obj_store);
2528
2529         return ret;
2530 }
2531
2532 /**
2533    \details Test WriteAndCommitStream (0x90) operation.
2534
2535    This function:
2536    -# Logs in 
2537    -# Opens the Outbox folder
2538    -# Creates a test message
2539    -# Creates an attachment on the test messages and set properties on the attachment
2540    -# Opens a stream on the attachment
2541    -# Sets the stream size
2542    -# Write and commits into the stream
2543    -# Saves the message
2544    -# Gets stream size and compare values
2545    -# Opens the stream again with different permissions
2546    -# Reads the stream and compares buffers
2547    -# Deletes the test message
2548
2549    \param mt pointer to the top-level mapitest structure
2550
2551    \return true on success, otherwise -1
2552  */
2553 _PUBLIC_ bool mapitest_oxcprpt_WriteAndCommitStream(struct mapitest *mt)
2554 {
2555         enum MAPISTATUS         retval;
2556         bool                    ret = true;
2557         mapi_object_t           obj_store;
2558         mapi_object_t           obj_folder;
2559         mapi_object_t           obj_message;
2560         mapi_object_t           obj_attach;
2561         mapi_object_t           obj_stream;
2562         mapi_id_t               id_folder;
2563         DATA_BLOB               data;
2564         struct SPropValue       attach[3];
2565         char                    *stream = NULL;
2566         char                    *out_stream = NULL;
2567         const uint32_t          stream_len = 0x1000;
2568         unsigned char           buf[0x1000];
2569         uint32_t                StreamSize = 0;
2570         uint16_t                read_size = 0;
2571         uint16_t                write_len = 0;
2572         uint32_t                offset = 0;
2573
2574
2575         stream = mapitest_common_genblob(mt->mem_ctx, stream_len);
2576         if (stream == NULL) {
2577                 return false;
2578         }
2579
2580         /* Step 1. Logon */
2581         mapi_object_init(&obj_store);
2582         retval = OpenMsgStore(mt->session, &obj_store);
2583         mapitest_print_retval(mt, "OpenMsgStore");
2584         if (retval != MAPI_E_SUCCESS) {
2585                 return false;
2586         }
2587
2588         /* Step 2. Open Inbox folder */
2589         retval = GetDefaultFolder(&obj_store, &id_folder, olFolderInbox);
2590         mapitest_print_retval(mt, "GetDefaultFolder");
2591         if (retval != MAPI_E_SUCCESS) {
2592                 return false;
2593         }
2594
2595         mapi_object_init(&obj_folder);
2596         retval = OpenFolder(&obj_store, id_folder, &obj_folder);
2597         mapitest_print_retval(mt, "OpenFolder");
2598         if (retval != MAPI_E_SUCCESS) {
2599                 return false;
2600         }
2601
2602         /* Step 3. Create the message */
2603         mapi_object_init(&obj_message);
2604         ret = mapitest_common_message_create(mt, &obj_folder, &obj_message, MT_MAIL_SUBJECT);
2605         mapitest_print_retval(mt, "Message Creation");
2606         if (ret != true) {
2607                 return false;
2608         }
2609
2610         /* Step 4. Create the attachment */
2611         mapi_object_init(&obj_attach);
2612         retval = CreateAttach(&obj_message, &obj_attach);
2613         mapitest_print_retval(mt, "CreateAttach");
2614         if (retval != MAPI_E_SUCCESS) {
2615                 ret = false;
2616         }
2617
2618         attach[0].ulPropTag = PR_ATTACH_METHOD;
2619         attach[0].value.l = ATTACH_BY_VALUE;
2620         attach[1].ulPropTag = PR_RENDERING_POSITION;
2621         attach[1].value.l = 0;
2622         attach[2].ulPropTag = PR_ATTACH_FILENAME;
2623         attach[2].value.lpszA = MT_MAIL_ATTACH;
2624
2625         retval = SetProps(&obj_attach, attach, 3);
2626         if (retval != MAPI_E_SUCCESS) {
2627                 ret = false;
2628         }
2629
2630         /* Step 5. Open the stream */
2631         mapi_object_init(&obj_stream);
2632         retval = OpenStream(&obj_attach, PR_ATTACH_DATA_BIN, 2, &obj_stream);
2633         mapitest_print_retval(mt, "OpenStream");
2634         if (retval != MAPI_E_SUCCESS) {
2635                 ret = false;
2636         }
2637
2638         /* Step 6. Set the stream size */
2639         retval = SetStreamSize(&obj_stream, (uint64_t) stream_len);
2640         mapitest_print_retval(mt, "SetStreamSize");
2641         if (retval != MAPI_E_SUCCESS) {
2642                 ret = false;
2643         }
2644
2645         /* Step 7. Write the stream */
2646         write_len = 0;
2647
2648         data.length = stream_len;
2649         data.data = (uint8_t *) stream;
2650         retval = WriteAndCommitStream(&obj_stream, &data, &write_len);
2651         mapitest_print_retval_fmt_clean(mt, "WriteAndCommitStream", retval, "(0x%x bytes written)", write_len);
2652         if (retval != MAPI_E_SUCCESS) {
2653                 ret = false;
2654         }
2655
2656         /* Step 8. Save the attachment */
2657         retval = SaveChangesAttachment(&obj_message, &obj_attach, KeepOpenReadOnly);
2658         mapitest_print_retval_clean(mt, "SaveChangesAttachment", retval);
2659         if (retval != MAPI_E_SUCCESS) {
2660                 ret = false;
2661         }
2662
2663         retval = SaveChangesMessage(&obj_folder, &obj_message, KeepOpenReadOnly);
2664         mapitest_print_retval_clean(mt, "SaveChangesMessage", retval);
2665         if (retval != MAPI_E_SUCCESS) {
2666                 ret = false;
2667         }
2668
2669         /* Step 9. Get stream size */
2670         retval = GetStreamSize(&obj_stream, &StreamSize);
2671         mapitest_print_retval_clean(mt, "GetStreamSize", retval);
2672         if (retval != MAPI_E_SUCCESS) {
2673                 ret = false;
2674         }
2675         mapitest_print(mt, "* %-35s: %s\n", "StreamSize comparison", 
2676                        (StreamSize == stream_len) ? "[PASSED]" : "[FAILURE]");
2677
2678         /* Step 10. Read the stream */
2679         mapi_object_release(&obj_stream);
2680         mapi_object_init(&obj_stream);
2681
2682         retval = OpenStream(&obj_attach, PR_ATTACH_DATA_BIN, 0, &obj_stream);
2683         mapitest_print_retval_clean(mt, "OpenStream", retval);
2684         if (retval != MAPI_E_SUCCESS) {
2685                 ret = false;
2686         }
2687
2688         offset = 0;
2689         out_stream = talloc_size(mt->mem_ctx, StreamSize + 1);
2690         do {
2691                 retval = ReadStream(&obj_stream, buf, MT_STREAM_MAX_SIZE, &read_size);
2692                 mapitest_print_retval_fmt_clean(mt, "ReadStream", retval, "(0x%x bytes read)", read_size);
2693                 memcpy(out_stream + offset, buf, read_size);
2694                 offset += read_size;
2695                 if (retval != MAPI_E_SUCCESS) {
2696                         ret = false;
2697                         break;
2698                 }
2699         } while (read_size && (offset != StreamSize));
2700         out_stream[offset] = '\0';
2701
2702         if (offset) {
2703                 if (!strcmp(stream, out_stream)) {
2704                         mapitest_print(mt, "* %-35s: [IN,OUT] stream [PASSED]\n", "Comparison");
2705                 } else {
2706                         mapitest_print(mt, "* %-35s: [IN,OUT] stream [FAILURE]\n", "Comparison");
2707
2708                 }
2709         }
2710
2711         /* Release */
2712         mapi_object_release(&obj_stream);
2713         mapi_object_release(&obj_attach);
2714         mapi_object_release(&obj_message);
2715         mapi_object_release(&obj_folder);
2716         mapi_object_release(&obj_store);
2717
2718         talloc_free(stream);
2719         talloc_free(out_stream);
2720
2721         return ret;
2722 }
2723