2 OpenChange MAPI torture suite implementation.
4 Test Named properties and IMAPIProp associated functions
6 Copyright (C) Julien Kerihuel 2007.
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program. If not, see <http://www.gnu.org/licenses/>.
22 #include <libmapi/libmapi.h>
23 #include <gen_ndr/ndr_exchange.h>
25 #include <credentials.h>
26 #include <torture/mapi_torture.h>
28 #include <torture/torture_proto.h>
29 #include <samba/popt.h>
31 #define NAMEDPROP_NAME "torture_namedprops"
32 #define NAMEDPROP_VALUE "Can you see me?"
34 bool torture_rpc_mapi_namedprops(struct torture_context *torture)
37 enum MAPISTATUS retval;
38 struct dcerpc_pipe *p;
41 struct mapi_session *session;
43 mapi_object_t obj_store;
44 mapi_object_t obj_folder;
45 mapi_object_t obj_table;
46 mapi_object_t obj_message;
47 struct SRowSet SRowSet;
48 struct SPropTagArray *SPropTagArray;
49 struct SPropValue *propvals;
50 struct mapi_SPropValue_array props_array;
54 struct MAPINAMEID *nameid;
59 mem_ctx = talloc_init("torture_rpc_mapi_namedprops");
60 status = torture_rpc_connection(torture, &p, &ndr_table_exchange_emsmdb);
61 if (!NT_STATUS_IS_OK(status)) {
67 if ((session = torture_init_mapi(mem_ctx, torture->lp_ctx)) == NULL) return false;
70 mapi_object_init(&obj_store);
71 retval = OpenMsgStore(session, &obj_store);
72 if (retval != MAPI_E_SUCCESS) return false;
74 /* Retrieve the specified folder ID */
75 retval = GetDefaultFolder(&obj_store, &id_folder, olFolderInbox);
76 if (retval != MAPI_E_SUCCESS) return false;
79 mapi_object_init(&obj_folder);
80 retval = OpenFolder(&obj_store, id_folder, &obj_folder);
81 if (retval != MAPI_E_SUCCESS) return false;
83 /* Retrieve the folder contents */
84 mapi_object_init(&obj_table);
85 retval = GetContentsTable(&obj_folder, &obj_table, 0, NULL);
86 if (retval != MAPI_E_SUCCESS) return false;
88 SPropTagArray = set_SPropTagArray(mem_ctx, 0x8,
97 retval = SetColumns(&obj_table, SPropTagArray);
98 MAPIFreeBuffer(SPropTagArray);
99 if (retval != MAPI_E_SUCCESS) return false;
101 retval = QueryRows(&obj_table, 0x32, TBL_ADVANCE, &SRowSet);
102 if (retval != MAPI_E_SUCCESS) return false;
104 /* We just need to open the first message for this test */
105 if (SRowSet.cRows == 0) {
106 printf("No messages in Mailbox\n");
107 talloc_free(mem_ctx);
111 mapi_object_init(&obj_message);
112 retval = OpenMessage(&obj_folder,
113 SRowSet.aRow[0].lpProps[0].value.d,
114 SRowSet.aRow[0].lpProps[1].value.d,
115 &obj_message, MAPI_MODIFY|MAPI_CREATE);
116 if (retval != MAPI_E_SUCCESS) return false;
118 retval = GetPropsAll(&obj_message, &props_array);
119 if (retval != MAPI_E_SUCCESS) return false;
121 /* loop through properties, search for named properties
122 * (0x8000-0xFFFE range) and call GetNamesFromIDs
124 printf("\n\n1. GetNamesFromIDs\n");
125 for (i = 0; i < props_array.cValues; i++) {
126 propID = props_array.lpProps[i].ulPropTag >> 16;
127 if (propID >= 0x8000 && propID <= 0xFFFE) {
128 propID = props_array.lpProps[i].ulPropTag;
129 propID = (propID & 0xFFFF0000) | PT_NULL;
130 nameid = talloc_zero(mem_ctx, struct MAPINAMEID);
131 retval = GetNamesFromIDs(&obj_message, propID, &count, &nameid);
132 if (retval != MAPI_E_SUCCESS) return false;
133 switch (nameid->ulKind) {
135 printf("\t0x%.8x mapped to 0x%.4x\n",
136 propID | (props_array.lpProps[i].ulPropTag & 0xFFFF), nameid->kind.lid);
139 printf("\t0x%.8x mapped to %s\n",
140 propID, nameid->kind.lpwstr.Name);
148 * Retrieve all the named properties for the current object
149 * This function seems to be the only one accepting 0 for
150 * input ulPropTag and returning the whole set of named properties
152 printf("\n\n2. QueryNamedProperties\n");
153 nameid = talloc_zero(mem_ctx, struct MAPINAMEID);
154 propIDs = talloc_zero(mem_ctx, uint16_t);
155 retval = QueryNamedProperties(&obj_message, 0, NULL, &count, &propIDs, &nameid);
156 mapi_errstr("QueryNamedProperties", GetLastError());
157 if (retval != MAPI_E_SUCCESS) return false;
159 for (i = 0; i < count; i++) {
162 printf("0x%.4x:\n", propIDs[i]);
164 guid = GUID_string(mem_ctx, &nameid[i].lpguid);
165 printf("\tguid: %s\n", guid);
168 switch (nameid[i].ulKind) {
170 printf("\tmapped to 0x%.4x\n", nameid[i].kind.lid);
173 printf("\tmapped to %s\n", nameid[i].kind.lpwstr.Name);
177 talloc_free(propIDs);
180 * finally call GetIDsFromNames with the Names retrieved in
183 printf("\n\n3. GetIDsFromNames\n");
184 for (i = 0; i < count; i++) {
185 SPropTagArray = talloc_zero(mem_ctx, struct SPropTagArray);
186 retval = GetIDsFromNames(&obj_folder, 1, &nameid[i], 0, &SPropTagArray);
187 switch (nameid[i].ulKind) {
189 printf("0x%.4x mapped to ", nameid[i].kind.lid);
192 printf("%s mapped to ", nameid[i].kind.lpwstr.Name);
195 mapidump_SPropTagArray(SPropTagArray);
196 talloc_free(SPropTagArray);
202 * Try to create a named property
207 printf("\n\n4. GetIDsFromNames (Create named property)\n");
208 GUID_from_string(PS_INTERNET_HEADERS, &guid);
209 nameid = talloc_zero(mem_ctx, struct MAPINAMEID);
210 SPropTagArray = talloc_zero(mem_ctx, struct SPropTagArray);
212 nameid[0].lpguid = guid;
213 nameid[0].ulKind = MNID_STRING;
214 nameid[0].kind.lpwstr.Name = NAMEDPROP_NAME;
215 nameid[0].kind.lpwstr.NameSize = strlen(NAMEDPROP_NAME) * 2 + 2;
216 retval = GetIDsFromNames(&obj_folder, 1, &nameid[0], MAPI_CREATE, &SPropTagArray);
217 if (retval != MAPI_E_SUCCESS) return false;
218 mapi_errstr("GetIDsFromNames", GetLastError());
220 printf("%s mapped to 0x%.8x\n", NAMEDPROP_NAME, SPropTagArray->aulPropTag[0]);
221 propID = SPropTagArray->aulPropTag[0] | PT_STRING8;
224 talloc_free(SPropTagArray);
228 * Assign its value with SetProps and save changes
231 struct SPropValue props[1];
232 const char *testval = NAMEDPROP_VALUE;
234 printf("\n\n5. Assigning %s to %s\n", NAMEDPROP_VALUE, NAMEDPROP_NAME);
236 set_SPropValue_proptag(&props[0], propID, (const void *)testval);
237 retval = SetProps(&obj_message, props, 1);
238 if (retval != MAPI_E_SUCCESS) return false;
239 mapi_errstr("SetProps", GetLastError());
241 retval = SaveChangesMessage(&obj_folder, &obj_message, KeepOpenReadOnly);
242 mapi_errstr("SaveChangesMessage", GetLastError());
243 if (retval != MAPI_E_SUCCESS) return false;
246 printf("\n\n6. GetNamesFromIDs (Fetch torture_namedprops property)\n");
247 propID = (propID & 0xFFFF0000)| PT_NULL;
248 retval = GetNamesFromIDs(&obj_message, propID, &count, &nameid);
249 mapi_errstr("GetNamesFromIDs", GetLastError());
250 if (retval != MAPI_E_SUCCESS) return false;
251 switch (nameid->ulKind) {
253 printf("\t0x%.8x mapped to 0x%.4x\n",
254 propID | (props_array.lpProps[i].ulPropTag & 0xFFFF), nameid->kind.lid);
257 printf("\t0x%.8x mapped to %s\n",
258 propID, nameid->kind.lpwstr.Name);
263 printf("\n\n7. GetProps (torture_namedprops property)\n");
264 propID = (propID & 0xFFFF0000) | PT_STRING8;
265 SPropTagArray = set_SPropTagArray(mem_ctx, 0x1, propID);
266 retval = GetProps(&obj_message, SPropTagArray, &propvals, &cn_propvals);
267 MAPIFreeBuffer(SPropTagArray);
268 mapi_errstr("GetProps", GetLastError());
269 if (retval != MAPI_E_SUCCESS) return false;
271 mapidump_SPropValue(propvals[0], "\t");
272 MAPIFreeBuffer(propvals);
274 mapi_object_release(&obj_message);
275 mapi_object_release(&obj_folder);
276 mapi_object_release(&obj_store);
278 /* Uninitialize MAPI */
280 talloc_free(mem_ctx);