2 OpenChange MAPI implementation.
4 Copyright (C) Julien Kerihuel 2007-2008.
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program. If not, see <http://www.gnu.org/licenses/>.
20 #include "libmapi/libmapi.h"
21 #include "libmapi/libmapi_private.h"
25 \file IMAPIContainer.c
27 \brief Containers and tables related operations
32 \details Returns a pointer to a container's table object
34 This function takes a pointer to a container object and returns a
35 pointer to its associated contents
37 \param obj_container the object to get the contents of
38 \param obj_table the resulting table containing the container's
40 \param TableFlags flags controlling the type of table
41 \param RowCount the number of rows in the hierarchy table
43 TableFlags possible values:
45 - TableFlags_Associated (0x2): Get the contents table for "Folder Associated
46 Information" messages, rather than normal messages.
48 - TableFlags_DeferredErrors (0x8): The call response can return immediately,
49 possibly before the call execution is complete and in this case the
50 ReturnValue as well the RowCount fields in the return buffer might
51 not be accurate. Only retval reporting failure can be considered
54 - TableFlags_NoNotifications (0x10): Disables all notifications on .this Table
57 - TableFlags_SoftDeletes (0x20): Enables the client to get a list of the soft
60 - TableFlags_UseUnicode (0x40): Requests that the columns that contain string
61 data be returned in Unicode format.
63 - TableFlags_SuppressNotifications (0x80): Suppresses notifications generated
64 by this client’s actions on this Table object.
66 Developers can either set RowCount to a valid pointer on uint32_t
67 or set it to NULL. In this last case, GetHierarchyTable won't
68 return any value to the calling function.
70 \return MAPI_E_SUCCESS on success, otherwise MAPI error.
72 \note Developers may also call GetLastError() to retrieve the last
73 MAPI error code. Possible MAPI error codes are:
74 - MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized
75 - MAPI_E_CALL_FAILED: A network problem was encountered during the
78 \sa OpenFolder, GetHierarchyTable, GetLastError
80 _PUBLIC_ enum MAPISTATUS GetContentsTable(mapi_object_t *obj_container, mapi_object_t *obj_table,
81 uint8_t TableFlags, uint32_t *RowCount)
83 struct mapi_request *mapi_request;
84 struct mapi_response *mapi_response;
85 struct EcDoRpc_MAPI_REQ *mapi_req;
86 struct GetContentsTable_req request;
87 struct mapi_session *session;
89 enum MAPISTATUS retval;
95 OPENCHANGE_RETVAL_IF(!obj_container, MAPI_E_INVALID_PARAMETER, NULL);
97 session = mapi_object_get_session(obj_container);
98 OPENCHANGE_RETVAL_IF(!session, MAPI_E_INVALID_PARAMETER, NULL);
100 if ((retval = mapi_object_get_logon_id(obj_container, &logon_id)) != MAPI_E_SUCCESS)
103 mem_ctx = talloc_named(session, 0, "GetContentsTable");
106 /* Fill the GetContentsTable operation */
107 request.handle_idx = 0x1;
108 request.TableFlags = TableFlags;
111 /* Fill the MAPI_REQ request */
112 mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ);
113 mapi_req->opnum = op_MAPI_GetContentsTable;
114 mapi_req->logon_id = logon_id;
115 mapi_req->handle_idx = 0;
116 mapi_req->u.mapi_GetContentsTable = request;
119 /* Fill the mapi_request structure */
120 mapi_request = talloc_zero(mem_ctx, struct mapi_request);
121 mapi_request->mapi_len = size + sizeof (uint32_t) * 2;
122 mapi_request->length = size;
123 mapi_request->mapi_req = mapi_req;
124 mapi_request->handles = talloc_array(mem_ctx, uint32_t, 2);
125 mapi_request->handles[0] = mapi_object_get_handle(obj_container);
126 mapi_request->handles[1] = 0xffffffff;
128 status = emsmdb_transaction_wrapper(session, mem_ctx, mapi_request, &mapi_response);
129 OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx);
130 OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx);
131 retval = mapi_response->mapi_repl->error_code;
132 OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
134 OPENCHANGE_CHECK_NOTIFICATION(session, mapi_response);
136 /* set object session, handle and logon_id */
137 mapi_object_set_session(obj_table, session);
138 mapi_object_set_handle(obj_table, mapi_response->handles[1]);
139 mapi_object_set_logon_id(obj_table, logon_id);
141 /* Retrieve RowCount if a valid pointer was set */
143 *RowCount = mapi_response->mapi_repl->u.mapi_GetContentsTable.RowCount;
147 mapi_object_table_init((TALLOC_CTX *)session, obj_table);
149 talloc_free(mapi_response);
150 talloc_free(mem_ctx);
152 return MAPI_E_SUCCESS;
157 \details Returns a pointer to a container's table object
159 This function takes a pointer to a container object and returns a
160 pointer to its associated hierarchy table
162 \param obj_container the object to get the contents of
163 \param obj_table the resulting table containing the container's
165 \param TableFlags flags controlling the type of table
166 \param RowCount the number of rows in the hierarchy table
168 TableFlags possible values:
170 - TableFlags_Depth (0x4): Fills the hierarchy table with containers
171 from all levels. If this flag is not set, the hierarchy table
172 contains only the container's immediate child containers.
174 - TableFlags_DeferredErrors (0x8): The call response can return immediately,
175 possibly before the call execution is complete and in this case the
176 ReturnValue as well the RowCount fields in the return buffer might
177 not be accurate. Only retval reporting failure can be considered
180 - TableFlags_NoNotifications (0x10): Disables all notifications on .this Table
183 - TableFlags_SoftDeletes (0x20): Enables the client to get a list of the soft
186 - TableFlags_UseUnicode (0x40): Requests that the columns that contain string
187 data be returned in Unicode format.
189 - TableFlags_SuppressNotifications (0x80): Suppresses notifications generated
190 by this client’s actions on this Table object.
192 Developers can either set RowCount to a valid pointer on uint32_t
193 or set it to NULL. In this last case, GetHierarchyTable won't
194 return any value to the calling function.
196 \return MAPI_E_SUCCESS on success, otherwise MAPI error.
198 \note Developers may also call GetLastError() to retrieve the last
199 MAPI error code. Possible MAPI error codes are:
200 - MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized
201 - MAPI_E_CALL_FAILED: A network problem was encountered during the
204 \sa OpenFolder, GetContentsTable, GetLastError
206 _PUBLIC_ enum MAPISTATUS GetHierarchyTable(mapi_object_t *obj_container, mapi_object_t *obj_table,
207 uint8_t TableFlags, uint32_t *RowCount)
209 struct mapi_request *mapi_request;
210 struct mapi_response *mapi_response;
211 struct EcDoRpc_MAPI_REQ *mapi_req;
212 struct GetHierarchyTable_req request;
213 struct mapi_session *session;
215 enum MAPISTATUS retval;
221 OPENCHANGE_RETVAL_IF(!obj_container, MAPI_E_INVALID_PARAMETER, NULL);
223 session = mapi_object_get_session(obj_container);
224 OPENCHANGE_RETVAL_IF(!session, MAPI_E_INVALID_PARAMETER, NULL);
226 if ((retval = mapi_object_get_logon_id(obj_container, &logon_id)) != MAPI_E_SUCCESS)
229 mem_ctx = talloc_named(session, 0, "GetHierarchyTable");
232 /* Fill the GetHierarchyTable operation */
233 request.handle_idx = 0x1;
234 request.TableFlags = TableFlags;
237 /* Fill the MAPI_REQ request */
238 mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ);
239 mapi_req->opnum = op_MAPI_GetHierarchyTable;
240 mapi_req->logon_id = logon_id;
241 mapi_req->handle_idx = 0;
242 mapi_req->u.mapi_GetHierarchyTable = request;
245 /* Fill the mapi_request structure */
246 mapi_request = talloc_zero(mem_ctx, struct mapi_request);
247 mapi_request->mapi_len = size + sizeof (uint32_t) * 2;
248 mapi_request->length = size;
249 mapi_request->mapi_req = mapi_req;
250 mapi_request->handles = talloc_array(mem_ctx, uint32_t, 2);
251 mapi_request->handles[0] = mapi_object_get_handle(obj_container);
252 mapi_request->handles[1] = 0xffffffff;
254 status = emsmdb_transaction_wrapper(session, mem_ctx, mapi_request, &mapi_response);
255 OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx);
256 OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx);
257 retval = mapi_response->mapi_repl->error_code;
258 OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
260 OPENCHANGE_CHECK_NOTIFICATION(session, mapi_response);
262 /* set object session, handle and logon_id */
263 mapi_object_set_session(obj_table, session);
264 mapi_object_set_handle(obj_table, mapi_response->handles[1]);
265 mapi_object_set_logon_id(obj_table, logon_id);
267 /* Retrieve RowCount if a valid pointer was set */
269 *RowCount = mapi_response->mapi_repl->u.mapi_GetHierarchyTable.RowCount;
273 mapi_object_table_init((TALLOC_CTX *)session, obj_table);
275 talloc_free(mapi_response);
276 talloc_free(mem_ctx);
278 return MAPI_E_SUCCESS;
283 \details Returns a pointer to the permission's table object.
285 This function takes a pointer to a container object and returns a
286 pointer to its associated permission table
288 \param obj_container the object to get the contents of
289 \param flags any special flags to pass
290 \param obj_table the resulting table containing the container's
293 \return MAPI_E_SUCCESS on success, otherwise MAPI error.
295 The only meaningful value for flags is IncludeFreeBusy (0x02). This
296 should be set when getting permissions on the Calendar folder when
297 using Exchange 2007 and later. It should not be set in other situations.
299 \note Developers may also call GetLastError() to retrieve the last
300 MAPI error code. Possible MAPI error codes are:
301 - MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized
302 - MAPI_E_CALL_FAILED: A network problem was encountered during the
305 \sa ModifyPermissions
307 _PUBLIC_ enum MAPISTATUS GetPermissionsTable(mapi_object_t *obj_container, uint8_t flags, mapi_object_t *obj_table)
309 struct mapi_request *mapi_request;
310 struct mapi_response *mapi_response;
311 struct EcDoRpc_MAPI_REQ *mapi_req;
312 struct GetPermissionsTable_req request;
313 struct mapi_session *session;
315 enum MAPISTATUS retval;
321 OPENCHANGE_RETVAL_IF(!obj_container, MAPI_E_INVALID_PARAMETER, NULL);
323 session = mapi_object_get_session(obj_container);
324 OPENCHANGE_RETVAL_IF(!session, MAPI_E_INVALID_PARAMETER, NULL);
326 if ((retval = mapi_object_get_logon_id(obj_container, &logon_id)) != MAPI_E_SUCCESS)
329 mem_ctx = talloc_named(session, 0, "GetPermissionsTable");
332 /* Fill the GetPermissionsTable operation */
333 request.handle_idx = 0x1;
334 request.TableFlags = flags;
337 /* Fill the MAPI_REQ request */
338 mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ);
339 mapi_req->opnum = op_MAPI_GetPermissionsTable;
340 mapi_req->logon_id = logon_id;
341 mapi_req->handle_idx= 0;
342 mapi_req->u.mapi_GetPermissionsTable = request;
345 /* Fill the mapi_request structure */
346 mapi_request = talloc_zero(mem_ctx, struct mapi_request);
347 mapi_request->mapi_len = size + sizeof (uint32_t) * 2;
348 mapi_request->length = size;
349 mapi_request->mapi_req = mapi_req;
350 mapi_request->handles = talloc_array(mem_ctx, uint32_t, 2);
351 mapi_request->handles[0] = mapi_object_get_handle(obj_container);
352 mapi_request->handles[1] = 0xffffffff;
354 status = emsmdb_transaction_wrapper(session, mem_ctx, mapi_request, &mapi_response);
355 OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx);
356 OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx);
357 retval = mapi_response->mapi_repl->error_code;
358 OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
360 OPENCHANGE_CHECK_NOTIFICATION(session, mapi_response);
362 /* set object session, handle and logon_id */
363 mapi_object_set_session(obj_table, session);
364 mapi_object_set_handle(obj_table, mapi_response->handles[1]);
365 mapi_object_set_logon_id(obj_table, logon_id);
368 mapi_object_table_init((TALLOC_CTX *)session, obj_table);
370 talloc_free(mapi_response);
371 talloc_free(mem_ctx);
373 return MAPI_E_SUCCESS;
378 \details Gets the rules table of a folder
380 \param obj_folder the folder we want to retrieve the rules table
382 \param obj_table the rules table
383 \param TableFlags bitmask associated to the rules table
385 Possible values for TableFlags:
387 - RulesTableFlags_Unicode (0x40): Set if the client is requesting
388 that string values in the table to be returned as Unicode
391 \return MAPI_E_SUCCESS on success, otherwise MAPI error.
393 \note Developers may also call GetLastError() to retrieve the last
394 MAPI error code. Possible MAPI error codes are:
395 - MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized
396 - MAPI_E_CALL_FAILED: A network problem was encountered during the
399 _PUBLIC_ enum MAPISTATUS GetRulesTable(mapi_object_t *obj_folder,
400 mapi_object_t *obj_table,
403 struct mapi_request *mapi_request;
404 struct mapi_response *mapi_response;
405 struct EcDoRpc_MAPI_REQ *mapi_req;
406 struct GetRulesTable_req request;
407 struct mapi_session *session;
409 enum MAPISTATUS retval;
415 OPENCHANGE_RETVAL_IF(!obj_folder, MAPI_E_INVALID_PARAMETER, NULL);
416 OPENCHANGE_RETVAL_IF(!obj_table, MAPI_E_INVALID_PARAMETER, NULL);
418 session = mapi_object_get_session(obj_folder);
419 OPENCHANGE_RETVAL_IF(!session, MAPI_E_INVALID_PARAMETER, NULL);
421 if ((retval = mapi_object_get_logon_id(obj_folder, &logon_id)) != MAPI_E_SUCCESS)
424 mem_ctx = talloc_named(session, 0, "GetRulesTable");
427 /* Fill the GetRulesTable operation */
428 request.handle_idx = 0x1;
429 size += sizeof (uint8_t);
431 request.TableFlags = TableFlags;
432 size += sizeof (uint8_t);
434 /* Fill the MAPI_REQ request */
435 mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ);
436 mapi_req->opnum = op_MAPI_GetRulesTable;
437 mapi_req->logon_id = logon_id;
438 mapi_req->handle_idx = 0;
439 mapi_req->u.mapi_GetRulesTable = request;
442 /* Fill the mapi_request structure */
443 mapi_request = talloc_zero(mem_ctx, struct mapi_request);
444 mapi_request->mapi_len = size + sizeof (uint32_t) * 2;
445 mapi_request->length = size;
446 mapi_request->mapi_req = mapi_req;
447 mapi_request->handles = talloc_array(mem_ctx, uint32_t, 2);
448 mapi_request->handles[0] = mapi_object_get_handle(obj_folder);
449 mapi_request->handles[1] = 0xffffffff;
451 status = emsmdb_transaction_wrapper(session, mem_ctx, mapi_request, &mapi_response);
452 OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx);
453 OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx);
454 retval = mapi_response->mapi_repl->error_code;
455 OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
457 OPENCHANGE_CHECK_NOTIFICATION(session, mapi_response);
459 /* set object session, handle and logon_id */
460 mapi_object_set_session(obj_table, session);
461 mapi_object_set_handle(obj_table, mapi_response->handles[1]);
462 mapi_object_set_logon_id(obj_table, logon_id);
465 mapi_object_table_init((TALLOC_CTX *)session, obj_table);
467 talloc_free(mapi_response);
468 talloc_free(mem_ctx);
470 return MAPI_E_SUCCESS;
476 \details Modify the entries of a permission table
478 This function takes a pointer to a table object, a list of entries
479 to modify and alter the permission table of its associated
480 container. This function can be used to add, modify or remove
483 \param obj_table the table containing the container's permissions
484 \param flags any special flags to use
485 \param permsdata the list of permissions table entries to modify
487 Possible values for flags:
489 - 0x02 for IncludeFreeBusy. This should be set when modifying permissions
490 on the Calendar folder when using Exchange 2007 and later. It should not
491 be set in other situations.
492 - 0x01 for ReplaceRows. This means "remove all current permissions and use
493 this set instead", so the permsdata must consist of ROW_ADD operations.
495 \return MAPI_E_SUCCESS on success, otherwise MAPI error.
497 \note Developers may also call GetLastError() to retrieve the last
498 MAPI error code. Possible MAPI error codes are:
499 - MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized
500 - MAPI_E_CALL_FAILED: A network problem was encountered during the
503 \sa GetPermissionsTable, AddUserPermission, ModifyUserPermission,
506 _PUBLIC_ enum MAPISTATUS ModifyPermissions(mapi_object_t *obj_table, uint8_t flags, struct mapi_PermissionsData *permsdata)
508 struct mapi_request *mapi_request;
509 struct mapi_response *mapi_response;
510 struct EcDoRpc_MAPI_REQ *mapi_req;
511 struct ModifyPermissions_req request;
512 struct mapi_session *session;
514 enum MAPISTATUS retval;
521 OPENCHANGE_RETVAL_IF(!obj_table, MAPI_E_INVALID_PARAMETER, NULL);
522 OPENCHANGE_RETVAL_IF(!permsdata, MAPI_E_INVALID_PARAMETER, NULL);
524 session = mapi_object_get_session(obj_table);
525 OPENCHANGE_RETVAL_IF(!session, MAPI_E_INVALID_PARAMETER, NULL);
527 if ((retval = mapi_object_get_logon_id(obj_table, &logon_id)) != MAPI_E_SUCCESS)
530 mem_ctx = talloc_named(session, 0, "ModifyPermissions");
532 /* Fill the ModifyPermissions operation */
533 request.rowList = *permsdata;
534 request.rowList.ModifyFlags = flags;
535 size += sizeof (uint8_t) + sizeof (uint16_t);
537 for (i = 0; i < permsdata->ModifyCount; i++) {
538 size += sizeof (uint8_t);
539 for (j = 0; j < permsdata->PermissionsData[i].lpProps.cValues; j++) {
540 size += get_mapi_property_size(&(permsdata->PermissionsData[i].lpProps.lpProps[j]));
541 size += sizeof (uint32_t);
543 size += sizeof (uint16_t);
546 /* Fill the MAPI_REQ request */
547 mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ);
548 mapi_req->opnum = op_MAPI_ModifyPermissions;
549 mapi_req->logon_id = logon_id;
550 mapi_req->handle_idx= 0;
551 mapi_req->u.mapi_ModifyPermissions = request;
554 /* Fill the mapi_request structure */
555 mapi_request = talloc_zero(mem_ctx, struct mapi_request);
556 mapi_request->mapi_len = size + sizeof (uint32_t);
557 mapi_request->length = size;
558 mapi_request->mapi_req = mapi_req;
559 mapi_request->handles = talloc_array(mem_ctx, uint32_t, 1);
560 mapi_request->handles[0] = mapi_object_get_handle(obj_table);
562 status = emsmdb_transaction_wrapper(session, mem_ctx, mapi_request, &mapi_response);
563 OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx);
564 OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx);
565 retval = mapi_response->mapi_repl->error_code;
566 OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
568 OPENCHANGE_CHECK_NOTIFICATION(session, mapi_response);
570 talloc_free(mapi_response);
571 talloc_free(mem_ctx);
573 return MAPI_E_SUCCESS;
577 \details Establishes search criteria for the container
579 \param obj_container the object we apply search criteria to
580 \param res pointer to a mapi_SRestriction structure defining the
582 \param SearchFlags bitmask of flags that controls how the search
584 \param lpContainerList pointer to a list of identifiers
585 representing containers to be included in the search
587 SearchFlags can take the following values:
589 - BACKGROUND_SEARCH: Search run at normal priority relative to
590 other searches. This flag is mutually exclusive with the
591 FOREGROUND_SEARCH one.
592 - FOREGROUND_SEARCH: Search run at high priority relative to other
593 searches. This flag is mutually exclusive with the
594 BACKGROUND_SEARCH one.
595 - RECURSIVE_SEARCH: The search should include the containers
596 specified in the lpContainerList parameter and all of their child
597 container. This flag is mutually exclusive with the
599 - RESTART_SEARCH: The search should be initiated, if this is the
600 first call to SetSearchCriteria, or restarted, if the search is
601 inactive. This flag is mutually exclusive with the STOP_SEARCH
603 - SHALLOW_SEARCH: The search should only look in the containers
604 specified in the lpContainerList parameter for matching
605 entries. This flag is mutually exclusive with the
606 RECURSIVE_SEARCH one.
607 - STOP_SEARCH: The search should be aborted. This flag is mutually
608 exclusive with the RESTART_SEARCH one.
610 \return MAPI_E_SUCCESS on success, otherwise MAPI error.
612 \note Developers may also call GetLastError() to retrieve the last
613 MAPI error code. Possible MAPI error codes are:
614 - MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized
615 - MAPI_E_INVALID_PARAMETER: One or more parameters were invalid (usually null pointer)
616 - MAPI_E_CALL_FAILED: A network problem was encountered during the
619 \sa GetSearchCriteria
621 _PUBLIC_ enum MAPISTATUS SetSearchCriteria(mapi_object_t *obj_container,
622 struct mapi_SRestriction *res,
623 uint32_t SearchFlags,
624 mapi_id_array_t *lpContainerList)
626 struct mapi_request *mapi_request;
627 struct mapi_response *mapi_response;
628 struct EcDoRpc_MAPI_REQ *mapi_req;
629 struct SetSearchCriteria_req request;
630 struct mapi_session *session;
632 enum MAPISTATUS retval;
638 OPENCHANGE_RETVAL_IF(!obj_container, MAPI_E_INVALID_PARAMETER, NULL);
639 OPENCHANGE_RETVAL_IF(!res, MAPI_E_INVALID_PARAMETER, NULL);
641 session = mapi_object_get_session(obj_container);
642 OPENCHANGE_RETVAL_IF(!session, MAPI_E_INVALID_PARAMETER, NULL);
644 if ((retval = mapi_object_get_logon_id(obj_container, &logon_id)) != MAPI_E_SUCCESS)
647 mem_ctx = talloc_named(session, 0, "SetSearchCriteria");
650 /* Fill the SetSearchCriteria operation */
652 size += get_mapi_SRestriction_size(res);
653 if (lpContainerList != NULL) {
654 request.FolderIdCount = lpContainerList->count;
655 size += sizeof (uint16_t);
657 mapi_id_array_get(mem_ctx, lpContainerList, &request.FolderIds);
658 size += lpContainerList->count * sizeof (uint64_t);
660 request.FolderIdCount = 0;
661 size += sizeof (uint16_t);
662 request.FolderIds = NULL;
664 request.SearchFlags = SearchFlags;
665 size += sizeof (uint32_t);
667 /* add subcontext size */
668 size += sizeof (uint16_t);
670 /* Fill the MAPI_REQ request */
671 mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ);
672 mapi_req->opnum = op_MAPI_SetSearchCriteria;
673 mapi_req->logon_id = logon_id;
674 mapi_req->handle_idx = 0;
675 mapi_req->u.mapi_SetSearchCriteria = request;
678 /* Fill the mapi_request structure */
679 mapi_request = talloc_zero(mem_ctx, struct mapi_request);
680 mapi_request->mapi_len = size + sizeof (uint32_t);
681 mapi_request->length = size;
682 mapi_request->mapi_req = mapi_req;
683 mapi_request->handles = talloc_array(mem_ctx, uint32_t, 1);
684 mapi_request->handles[0] = mapi_object_get_handle(obj_container);
686 status = emsmdb_transaction_wrapper(session, mem_ctx, mapi_request, &mapi_response);
687 OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx);
688 OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx);
689 retval = mapi_response->mapi_repl->error_code;
690 OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
692 OPENCHANGE_CHECK_NOTIFICATION(session, mapi_response);
694 talloc_free(mapi_response);
695 talloc_free(mem_ctx);
697 return MAPI_E_SUCCESS;
702 \details Obtains the search criteria for a container
704 \param obj_container the object we retrieve search criteria from
705 \param res pointer to a mapi_SRestriction structure defining the
707 \param SearchFlags bitmask of flags that controls how the search
709 \param FolderIdCount number of FolderIds entries
710 \param FolderIds pointer to a list of identifiers
711 representing containers included in the search
713 \return MAPI_E_SUCCESS on success, otherwise MAPI error.
715 \note Developers may also call GetLastError() to retrieve the last
716 MAPI error code. Possible MAPI error codes are:
717 - MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized
718 - MAPI_E_CALL_FAILED: A network problem was encountered during the
721 \sa SetSearchCriteria
723 _PUBLIC_ enum MAPISTATUS GetSearchCriteria(mapi_object_t *obj_container,
724 struct mapi_SRestriction *res,
725 uint32_t *SearchFlags,
726 uint16_t *FolderIdCount,
727 uint64_t **FolderIds)
729 struct mapi_request *mapi_request;
730 struct mapi_response *mapi_response;
731 struct EcDoRpc_MAPI_REQ *mapi_req;
732 struct GetSearchCriteria_req request;
733 struct GetSearchCriteria_repl *reply;
734 struct mapi_session *session;
736 enum MAPISTATUS retval;
742 OPENCHANGE_RETVAL_IF(!obj_container, MAPI_E_INVALID_PARAMETER, NULL);
743 OPENCHANGE_RETVAL_IF(!SearchFlags, MAPI_E_INVALID_PARAMETER, NULL);
744 OPENCHANGE_RETVAL_IF(!FolderIdCount, MAPI_E_INVALID_PARAMETER, NULL);
745 OPENCHANGE_RETVAL_IF(!FolderIds, MAPI_E_INVALID_PARAMETER, NULL);
747 session = mapi_object_get_session(obj_container);
748 OPENCHANGE_RETVAL_IF(!session, MAPI_E_INVALID_PARAMETER, NULL);
750 if ((retval = mapi_object_get_logon_id(obj_container, &logon_id)) != MAPI_E_SUCCESS)
753 mem_ctx = talloc_named(session, 0, "GetSearchCriteria");
756 /* Fill the GetSearchCriteria operation */
757 request.UseUnicode = 0x1;
758 request.IncludeRestriction = 0x1;
759 request.IncludeFolders = 0x1;
760 size += 3 * sizeof (uint8_t);
762 /* Fill the MAPI_REQ request */
763 mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ);
764 mapi_req->opnum = op_MAPI_GetSearchCriteria;
765 mapi_req->logon_id = logon_id;
766 mapi_req->handle_idx = 0;
767 mapi_req->u.mapi_GetSearchCriteria = request;
770 /* Fill the mapi_request structure */
771 mapi_request = talloc_zero(mem_ctx, struct mapi_request);
772 mapi_request->mapi_len = size + sizeof (uint32_t);
773 mapi_request->length = size;
774 mapi_request->mapi_req = mapi_req;
775 mapi_request->handles = talloc_array(mem_ctx, uint32_t, 1);
776 mapi_request->handles[0] = mapi_object_get_handle(obj_container);
778 status = emsmdb_transaction_wrapper(session, mem_ctx, mapi_request, &mapi_response);
779 OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx);
780 OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx);
781 retval = mapi_response->mapi_repl->error_code;
782 OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
784 OPENCHANGE_CHECK_NOTIFICATION(session, mapi_response);
786 reply = &mapi_response->mapi_repl->u.mapi_GetSearchCriteria;
788 res = &reply->RestrictionData;
789 *FolderIdCount = reply->FolderIdCount;
790 *FolderIds = talloc_steal((TALLOC_CTX *)session, reply->FolderIds);
791 *SearchFlags = reply->SearchFlags;
793 talloc_free(mapi_response);
794 talloc_free(mem_ctx);
796 return MAPI_E_SUCCESS;