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"
27 \brief Folders related operations
32 \details Open a folder from the store
34 \param obj_store the store to open a folder in (i.e. the parent)
35 \param id_folder the folder identifier
36 \param obj_folder the resulting open folder
38 \return MAPI_E_SUCCESS on success, otherwise MAPI error.
40 \note Developers may also call GetLastError() to retrieve the last
41 MAPI error code. Possible MAPI error codes are:
42 - MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized
43 - MAPI_E_CALL_FAILED: A network problem was encountered during the
46 \sa MAPIInitialize, OpenMsgStore, GetLastError
48 _PUBLIC_ enum MAPISTATUS OpenFolder(mapi_object_t *obj_store,
50 mapi_object_t *obj_folder)
52 struct mapi_request *mapi_request;
53 struct mapi_response *mapi_response;
54 struct EcDoRpc_MAPI_REQ *mapi_req;
55 struct OpenFolder_req request;
56 struct mapi_session *session;
58 enum MAPISTATUS retval;
64 OPENCHANGE_RETVAL_IF(!obj_store, MAPI_E_INVALID_PARAMETER, NULL);
65 session = mapi_object_get_session(obj_store);
66 OPENCHANGE_RETVAL_IF(!session, MAPI_E_INVALID_PARAMETER, NULL);
68 if ((retval = mapi_object_get_logon_id(obj_store, &logon_id)) != MAPI_E_SUCCESS)
71 mem_ctx = talloc_named(NULL, 0, "OpenFolder");
73 /* Fill the OpenFolder operation */
74 request.handle_idx = 0x1;
75 request.folder_id = id_folder;
76 request.OpenModeFlags = OpenModeFlags_Folder;
77 size += sizeof (uint8_t) + sizeof(uint64_t) + sizeof(uint8_t);
79 /* Fill the MAPI_REQ request */
80 mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ);
81 mapi_req->opnum = op_MAPI_OpenFolder;
82 mapi_req->logon_id = logon_id;
83 mapi_req->handle_idx = 0;
84 mapi_req->u.mapi_OpenFolder = request;
87 /* Fill the mapi_request structure */
88 mapi_request = talloc_zero(mem_ctx, struct mapi_request);
89 mapi_request->mapi_len = size + sizeof (uint32_t) * 2;
90 mapi_request->length = size;
91 mapi_request->mapi_req = mapi_req;
92 mapi_request->handles = talloc_array(mem_ctx, uint32_t, 2);
93 mapi_request->handles[0] = mapi_object_get_handle(obj_store);
94 mapi_request->handles[1] = 0xffffffff;
96 status = emsmdb_transaction_wrapper(session, mem_ctx, mapi_request, &mapi_response);
97 OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx);
98 OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx);
99 retval = mapi_response->mapi_repl->error_code;
100 OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
102 OPENCHANGE_CHECK_NOTIFICATION(session, mapi_response);
104 /* Set object session, id and handle */
105 mapi_object_set_session(obj_folder, session);
106 mapi_object_set_id(obj_folder, id_folder);
107 mapi_object_set_handle(obj_folder, mapi_response->handles[1]);
108 mapi_object_set_logon_id(obj_folder, logon_id);
110 talloc_free(mapi_response);
111 talloc_free(mem_ctx);
113 return MAPI_E_SUCCESS;
118 \details Determine if a public folder is ghosted.
120 This function returns whether a public folder is ghosted or not.
122 \param obj_store the store of the public folder
123 \param obj_folder the folder we are querying for ghost
124 \param IsGhosted pointer on the boolean value returned
126 \return MAPI_E_SUCCESS on success, otherwise MAPI error.
128 \note Developers may also call GetLastError() to retrieve the last
129 MAPI error code. Possible MAPI error codes are:
130 - MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized
131 - MAPI_E_CALL_FAILED: A network problem was encountered during the
134 _PUBLIC_ enum MAPISTATUS PublicFolderIsGhosted(mapi_object_t *obj_store,
135 mapi_object_t *obj_folder,
138 struct mapi_request *mapi_request;
139 struct mapi_response *mapi_response;
140 struct EcDoRpc_MAPI_REQ *mapi_req;
141 struct PublicFolderIsGhosted_req request;
142 struct mapi_session *session[2];
144 enum MAPISTATUS retval;
151 OPENCHANGE_RETVAL_IF(!obj_store, MAPI_E_INVALID_PARAMETER, NULL);
152 OPENCHANGE_RETVAL_IF(!obj_folder, MAPI_E_INVALID_PARAMETER, NULL);
154 session[0] = mapi_object_get_session(obj_store);
155 session[1] = mapi_object_get_session(obj_folder);
156 OPENCHANGE_RETVAL_IF(!session[0], MAPI_E_INVALID_PARAMETER, NULL);
157 OPENCHANGE_RETVAL_IF(!session[1], MAPI_E_INVALID_PARAMETER, NULL);
158 OPENCHANGE_RETVAL_IF(session[0] != session[1], MAPI_E_INVALID_PARAMETER, NULL);
160 if ((retval = mapi_object_get_logon_id(obj_store, &logon_id)) != MAPI_E_SUCCESS)
163 folderId = mapi_object_get_id(obj_folder);
164 OPENCHANGE_RETVAL_IF(!folderId, MAPI_E_INVALID_PARAMETER, NULL);
166 mem_ctx = talloc_named(NULL, 0, "PublicFolderIsGhosted");
169 /* Fill the PublicFolderIsGhosted operation */
170 request.FolderId = folderId;
171 size += sizeof (uint64_t);
173 /* Fill the MAPI_REQ request */
174 mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ);
175 mapi_req->opnum = op_MAPI_PublicFolderIsGhosted;
176 mapi_req->logon_id = logon_id;
177 mapi_req->handle_idx = 0;
178 mapi_req->u.mapi_PublicFolderIsGhosted = request;
181 /* Fill the mapi_request structure */
182 mapi_request = talloc_zero(mem_ctx, struct mapi_request);
183 mapi_request->mapi_len = size + sizeof (uint32_t);
184 mapi_request->length = size;
185 mapi_request->mapi_req = mapi_req;
186 mapi_request->handles = talloc_array(mem_ctx, uint32_t, 1);
187 mapi_request->handles[0] = mapi_object_get_handle(obj_store);
189 status = emsmdb_transaction_wrapper(session[0], mem_ctx, mapi_request, &mapi_response);
190 OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx);
191 OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx);
192 retval = mapi_response->mapi_repl->error_code;
193 OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
195 OPENCHANGE_CHECK_NOTIFICATION(session[0], mapi_response);
197 *IsGhosted = mapi_response->mapi_repl->u.mapi_PublicFolderIsGhosted.IsGhosted;
199 talloc_free(mapi_response);
200 talloc_free(mem_ctx);
202 return MAPI_E_SUCCESS;
207 \details Open a NNTP Public Folder given its name
209 \param obj_folder the parent folder
210 \param obj_child the resulting open folder
211 \param name the folder name
213 \return MAPI_E_SUCCESS on success, otherwise MAPI error.
215 \note Developers may also call GetLastError() to retrieve the last
216 MAPI error code. Possible MAPI error codes are:
217 - MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized
218 - MAPI_E_CALL_FAILED: A network problem was encountered during the
223 _PUBLIC_ enum MAPISTATUS OpenPublicFolderByName(mapi_object_t *obj_folder,
224 mapi_object_t *obj_child,
227 struct mapi_request *mapi_request;
228 struct mapi_response *mapi_response;
229 struct EcDoRpc_MAPI_REQ *mapi_req;
230 struct OpenPublicFolderByName_req request;
231 struct mapi_session *session;
233 enum MAPISTATUS retval;
239 OPENCHANGE_RETVAL_IF(!obj_folder, MAPI_E_INVALID_PARAMETER, NULL);
240 OPENCHANGE_RETVAL_IF(!obj_child, MAPI_E_INVALID_PARAMETER, NULL);
241 OPENCHANGE_RETVAL_IF(!name, MAPI_E_INVALID_PARAMETER, NULL);
242 session = mapi_object_get_session(obj_folder);
243 OPENCHANGE_RETVAL_IF(!session, MAPI_E_INVALID_PARAMETER, NULL);
245 if ((retval = mapi_object_get_logon_id(obj_folder, &logon_id)) != MAPI_E_SUCCESS)
248 mem_ctx = talloc_named(NULL, 0, "OpenPublicFolderByName");
251 /* Fill the OpenPublicFolderByName operation */
252 request.handle_idx = 0x1;
253 size += sizeof (uint8_t);
255 /* name is prefixed with 32 bit [size] */
257 size += strlen(name) + 1 + sizeof (uint32_t);
259 /* Fill the MAPI_REQ request */
260 mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ);
261 mapi_req->opnum = op_MAPI_OpenPublicFolderByName;
262 mapi_req->logon_id = logon_id;
263 mapi_req->handle_idx = 0;
264 mapi_req->u.mapi_OpenPublicFolderByName = request;
267 /* Fill the mapi_request structure */
268 mapi_request = talloc_zero(mem_ctx, struct mapi_request);
269 mapi_request->mapi_len = size + sizeof (uint32_t) * 2;
270 mapi_request->length = size;
271 mapi_request->mapi_req = mapi_req;
272 mapi_request->handles = talloc_array(mem_ctx, uint32_t, 2);
273 mapi_request->handles[0] = mapi_object_get_handle(obj_folder);
274 mapi_request->handles[1] = 0xffffffff;
276 status = emsmdb_transaction_wrapper(session, mem_ctx, mapi_request, &mapi_response);
277 OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx);
278 OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx);
279 retval = mapi_response->mapi_repl->error_code;
280 OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
282 OPENCHANGE_CHECK_NOTIFICATION(session, mapi_response);
284 /* Set object session and handle */
285 mapi_object_set_session(obj_child, session);
286 mapi_object_set_handle(obj_child, mapi_response->handles[1]);
287 mapi_object_set_logon_id(obj_child, logon_id);
289 talloc_free(mapi_response);
290 talloc_free(mem_ctx);
292 return MAPI_E_SUCCESS;
297 \details Sets a folder as the destination for incoming messages of
298 a particular message class.
300 \param obj_store the store to set the receive folder for
301 \param obj_folder the destination folder
302 \param lpszMessageClass the message class the folder will receive
304 \return MAPI_E_SUCCESS on success, otherwise MAPI error.
306 \note Developers may also call GetLastError() to retrieve the last
307 MAPI error code. Possible MAPI error codes are:
308 - MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized
309 - MAPI_E_CALL_FAILED: A network problem was encountered during the
312 \sa GetReceiveFolder, GetReceiveFolderTable
314 _PUBLIC_ enum MAPISTATUS SetReceiveFolder(mapi_object_t *obj_store,
315 mapi_object_t *obj_folder,
316 const char *lpszMessageClass)
318 struct mapi_request *mapi_request;
319 struct mapi_response *mapi_response;
320 struct EcDoRpc_MAPI_REQ *mapi_req;
321 struct SetReceiveFolder_req request;
322 struct mapi_session *session;
324 enum MAPISTATUS retval;
330 OPENCHANGE_RETVAL_IF(!obj_store, MAPI_E_INVALID_PARAMETER, NULL);
331 OPENCHANGE_RETVAL_IF(!obj_folder, MAPI_E_INVALID_PARAMETER, NULL);
332 OPENCHANGE_RETVAL_IF(!lpszMessageClass, MAPI_E_INVALID_PARAMETER, NULL);
333 session = mapi_object_get_session(obj_store);
334 OPENCHANGE_RETVAL_IF(!session, MAPI_E_INVALID_PARAMETER, NULL);
335 if ((retval = mapi_object_get_logon_id(obj_store, &logon_id)) != MAPI_E_SUCCESS)
338 mem_ctx = talloc_named(NULL, 0, "SetReceiveFolder");
340 /* Fill the SetReceiveFolder operation */
342 request.fid = mapi_object_get_id(obj_folder);
343 size += sizeof (uint64_t);
344 request.lpszMessageClass = lpszMessageClass;
345 size += strlen(lpszMessageClass) + 1;
347 /* Fill the MAPI_REQ request */
348 mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ);
349 mapi_req->opnum = op_MAPI_SetReceiveFolder;
350 mapi_req->logon_id = logon_id;
351 mapi_req->handle_idx = 0;
352 mapi_req->u.mapi_SetReceiveFolder = request;
355 /* Fill the mapi_request structure */
356 mapi_request = talloc_zero(mem_ctx, struct mapi_request);
357 mapi_request->mapi_len = size + sizeof (uint32_t);
358 mapi_request->length = size;
359 mapi_request->mapi_req = mapi_req;
360 mapi_request->handles = talloc_array(mem_ctx, uint32_t, 1);
361 mapi_request->handles[0] = mapi_object_get_handle(obj_store);
363 status = emsmdb_transaction_wrapper(session, mem_ctx, mapi_request, &mapi_response);
364 OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx);
365 OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx);
366 retval = mapi_response->mapi_repl->error_code;
367 OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
369 OPENCHANGE_CHECK_NOTIFICATION(session, mapi_response);
371 talloc_free(mapi_response);
372 talloc_free(mem_ctx);
374 return MAPI_E_SUCCESS;
379 \details Gets the receive folder for incoming messages of a
380 particular message class.
382 This function obtains the folder that was established as the
383 destination for incoming messages of a specified message class, or
384 the default receive folder for the message store.
386 \param obj_store the store to get the receiver folder for
387 \param id_folder the resulting folder identification
388 \param MessageClass which message class to find the receivefolder
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 \sa MAPIInitialize, OpenMsgStore, GetLastError, SetReceiveFolder,
400 GetReceiveFolderTable
402 _PUBLIC_ enum MAPISTATUS GetReceiveFolder(mapi_object_t *obj_store,
403 mapi_id_t *id_folder,
404 const char *MessageClass)
406 struct mapi_request *mapi_request;
407 struct mapi_response *mapi_response;
408 struct EcDoRpc_MAPI_REQ *mapi_req;
409 struct GetReceiveFolder_req request;
410 struct mapi_session *session;
412 enum MAPISTATUS retval;
418 OPENCHANGE_RETVAL_IF(!obj_store, MAPI_E_INVALID_PARAMETER, NULL);
419 session = mapi_object_get_session(obj_store);
420 OPENCHANGE_RETVAL_IF(!session, MAPI_E_INVALID_PARAMETER, NULL);
421 if ((retval = mapi_object_get_logon_id(obj_store, &logon_id)) != MAPI_E_SUCCESS)
424 mem_ctx = talloc_named(NULL, 0, "GetReceiveFolder");
428 /* Fill the GetReceiveFolder operation */
430 request.MessageClass = "";
433 request.MessageClass = MessageClass;
434 size += strlen (MessageClass) + 1;
437 /* Fill the MAPI_REQ request */
438 mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ);
439 mapi_req->opnum = op_MAPI_GetReceiveFolder;
440 mapi_req->logon_id = logon_id;
441 mapi_req->handle_idx = 0;
442 mapi_req->u.mapi_GetReceiveFolder = request;
445 /* Fill the mapi_request structure */
446 mapi_request = talloc_zero(mem_ctx, struct mapi_request);
447 mapi_request->mapi_len = size + sizeof (uint32_t);
448 mapi_request->length = size;
449 mapi_request->mapi_req = mapi_req;
450 mapi_request->handles = talloc_array(mem_ctx, uint32_t, 1);
451 mapi_request->handles[0] = mapi_object_get_handle(obj_store);
453 status = emsmdb_transaction_wrapper(session, mem_ctx, mapi_request, &mapi_response);
454 OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx);
455 OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx);
456 retval = mapi_response->mapi_repl->error_code;
457 OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
459 OPENCHANGE_CHECK_NOTIFICATION(session, mapi_response);
461 *id_folder = mapi_response->mapi_repl->u.mapi_GetReceiveFolder.folder_id;
463 talloc_free(mapi_response);
464 talloc_free(mem_ctx);
466 return MAPI_E_SUCCESS;
471 \details Retrieve the receive folder table which includes all the
472 information about the receive folders for the message store
474 \param obj_store the message store object
475 \param SRowSet pointer on a SRowSet structure with
476 GetReceiveFolderTable results.
478 Developers are required to call MAPIFreeBuffer(SRowSet.aRow) when
479 they don't need the folder table data anymore.
481 \return MAPI_E_SUCCESS on success, otherwise MAPI error.
483 \note Developers may also call GetLastError() to retrieve the last
484 MAPI error code. Possible MAPI error codes are:
485 - MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized
486 - MAPI_E_CALL_FAILED: A network problem was encountered during the
489 \sa GetReceiveFolder, SetReceiveFolder
491 _PUBLIC_ enum MAPISTATUS GetReceiveFolderTable(mapi_object_t *obj_store,
492 struct SRowSet *SRowSet)
494 struct mapi_request *mapi_request;
495 struct mapi_response *mapi_response;
496 struct EcDoRpc_MAPI_REQ *mapi_req;
497 struct GetReceiveFolderTable_repl *reply;
498 struct mapi_session *session;
500 enum MAPISTATUS retval;
507 OPENCHANGE_RETVAL_IF(!obj_store, MAPI_E_INVALID_PARAMETER, NULL);
508 session = mapi_object_get_session(obj_store);
509 OPENCHANGE_RETVAL_IF(!session, MAPI_E_INVALID_PARAMETER, NULL);
510 if ((retval = mapi_object_get_logon_id(obj_store, &logon_id)) != MAPI_E_SUCCESS)
513 mem_ctx = talloc_named(NULL, 0, "GetReceiveFolderTable");
516 /* Fill the MAPI_REQ request */
517 mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ);
518 mapi_req->opnum = op_MAPI_GetReceiveFolderTable;
519 mapi_req->logon_id = logon_id;
520 mapi_req->handle_idx = 0;
523 /* Fill the mapi_request structure */
524 mapi_request = talloc_zero(mem_ctx, struct mapi_request);
525 mapi_request->mapi_len = size + sizeof (uint32_t);
526 mapi_request->length = size;
527 mapi_request->mapi_req = mapi_req;
528 mapi_request->handles = talloc_array(mem_ctx, uint32_t, 1);
529 mapi_request->handles[0] = mapi_object_get_handle(obj_store);
531 status = emsmdb_transaction_wrapper(session, mem_ctx, mapi_request, &mapi_response);
532 OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx);
533 OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx);
534 retval = mapi_response->mapi_repl->error_code;
535 OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
537 OPENCHANGE_CHECK_NOTIFICATION(session, mapi_response);
539 reply = &mapi_response->mapi_repl->u.mapi_GetReceiveFolderTable;
541 /* Retrieve the ReceiveFolderTable entries */
542 SRowSet->cRows = reply->cValues;
543 SRowSet->aRow = talloc_array((TALLOC_CTX *)session, struct SRow, reply->cValues);
545 for (i = 0; i < reply->cValues; i++) {
546 SRowSet->aRow[i].ulAdrEntryPad = 0;
547 SRowSet->aRow[i].cValues = 3;
548 SRowSet->aRow[i].lpProps = talloc_array((TALLOC_CTX *)SRowSet->aRow, struct SPropValue,
549 SRowSet->aRow[i].cValues);
551 SRowSet->aRow[i].lpProps[0].ulPropTag = PR_FID;
552 SRowSet->aRow[i].lpProps[0].dwAlignPad = 0x0;
553 SRowSet->aRow[i].lpProps[0].value.d = reply->entries[i].fid;
555 if (reply->entries[i].lpszMessageClass && strlen(reply->entries[i].lpszMessageClass)) {
556 SRowSet->aRow[i].lpProps[1].ulPropTag = PR_MESSAGE_CLASS;
557 SRowSet->aRow[i].lpProps[1].dwAlignPad = 0x0;
558 SRowSet->aRow[i].lpProps[1].value.lpszA = talloc_strdup((TALLOC_CTX *)SRowSet->aRow[i].lpProps, reply->entries[i].lpszMessageClass);
560 SRowSet->aRow[i].lpProps[1].ulPropTag = PR_MESSAGE_CLASS;
561 SRowSet->aRow[i].lpProps[1].dwAlignPad = 0x0;
562 SRowSet->aRow[i].lpProps[1].value.lpszA = "";
565 SRowSet->aRow[i].lpProps[2].ulPropTag = PR_LAST_MODIFICATION_TIME;
566 SRowSet->aRow[i].lpProps[2].dwAlignPad = 0x0;
567 SRowSet->aRow[i].lpProps[2].value.ft.dwLowDateTime = reply->entries[i].modiftime.dwLowDateTime;
568 SRowSet->aRow[i].lpProps[2].value.ft.dwHighDateTime = reply->entries[i].modiftime.dwHighDateTime;
571 talloc_free(mapi_response);
572 talloc_free(mem_ctx);
574 return MAPI_E_SUCCESS;
579 \details Retrieves the folder ID of the temporary transport folder.
581 \param obj_store the server object
582 \param FolderId pointer on the returning Folder identifier
584 \return MAPI_E_SUCCESS on success, otherwise MAPI error.
586 \note Developers may also call GetLastError() to retrieve the last
587 MAPI error code. Possible MAPI error codes are:
588 - MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized
589 - MAPI_E_CALL_FAILED: A network problem was encountered during the
592 _PUBLIC_ enum MAPISTATUS GetTransportFolder(mapi_object_t *obj_store,
595 struct mapi_request *mapi_request;
596 struct mapi_response *mapi_response;
597 struct EcDoRpc_MAPI_REQ *mapi_req;
598 struct GetTransportFolder_repl *reply;
599 struct mapi_session *session;
601 enum MAPISTATUS retval;
607 OPENCHANGE_RETVAL_IF(!obj_store, MAPI_E_INVALID_PARAMETER, NULL);
608 OPENCHANGE_RETVAL_IF(!FolderId, MAPI_E_INVALID_PARAMETER, NULL);
609 session = mapi_object_get_session(obj_store);
610 OPENCHANGE_RETVAL_IF(!session, MAPI_E_INVALID_PARAMETER, NULL);
611 if ((retval = mapi_object_get_logon_id(obj_store, &logon_id)) != MAPI_E_SUCCESS)
614 mem_ctx = talloc_named(NULL, 0, "GetTransportFolder");
617 /* Fill the MAPI_REQ request */
618 mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ);
619 mapi_req->opnum = op_MAPI_GetTransportFolder;
620 mapi_req->logon_id = logon_id;
621 mapi_req->handle_idx = 0;
624 /* Fill the mapi_request structure */
625 mapi_request = talloc_zero(mem_ctx, struct mapi_request);
626 mapi_request->mapi_len = size + sizeof (uint32_t);
627 mapi_request->length = size;
628 mapi_request->mapi_req = mapi_req;
629 mapi_request->handles = talloc_array(mem_ctx, uint32_t, 1);
630 mapi_request->handles[0] = mapi_object_get_handle(obj_store);
632 status = emsmdb_transaction_wrapper(session, mem_ctx, mapi_request, &mapi_response);
633 OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx);
634 OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx);
635 retval = mapi_response->mapi_repl->error_code;
636 OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
638 OPENCHANGE_CHECK_NOTIFICATION(session, mapi_response);
640 /* Retrieve the FolderId parameter */
641 reply = &mapi_response->mapi_repl->u.mapi_GetTransportFolder;
642 *FolderId = reply->FolderId;
644 talloc_free(mapi_response);
645 talloc_free(mem_ctx);
647 return MAPI_E_SUCCESS;
652 \details Get the list of servers that host replicas of a given
655 \param obj_store the public folder store object
656 \param obj_folder the folder object we search replica for
657 \param OwningServersCount number of OwningServers
658 \param CheapServersCount number of low-cost servers
659 \param OwningServers pointer on the list of NULL terminated ASCII
660 string representing replica servers
662 \return MAPI_E_SUCCESS on success, otherwise MAPI error.
664 \note ecNoReplicaAvailable (0x469) can be returned if no replica is
665 available for the folder.
667 Developers may also call GetLastError() to retrieve the last
668 MAPI error code. Possible MAPI error codes are:
669 - MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized
670 - MAPI_E_CALL_FAILED: A network problem was encountered during the
673 _PUBLIC_ enum MAPISTATUS GetOwningServers(mapi_object_t *obj_store,
674 mapi_object_t *obj_folder,
675 uint16_t *OwningServersCount,
676 uint16_t *CheapServersCount,
677 char **OwningServers)
679 struct mapi_request *mapi_request;
680 struct mapi_response *mapi_response;
681 struct EcDoRpc_MAPI_REQ *mapi_req;
682 struct GetOwningServers_req request;
683 struct GetOwningServers_repl response;
684 struct mapi_session *session;
686 enum MAPISTATUS retval;
694 OPENCHANGE_RETVAL_IF(!obj_store, MAPI_E_INVALID_PARAMETER, NULL);
695 OPENCHANGE_RETVAL_IF(!obj_folder, MAPI_E_INVALID_PARAMETER, NULL);
696 OPENCHANGE_RETVAL_IF(!OwningServersCount, MAPI_E_INVALID_PARAMETER, NULL);
697 OPENCHANGE_RETVAL_IF(!CheapServersCount, MAPI_E_INVALID_PARAMETER, NULL);
698 OPENCHANGE_RETVAL_IF(!OwningServers, MAPI_E_INVALID_PARAMETER, NULL);
700 session = mapi_object_get_session(obj_store);
701 OPENCHANGE_RETVAL_IF(!session, MAPI_E_INVALID_PARAMETER, NULL);
703 if ((retval = mapi_object_get_logon_id(obj_store, &logon_id)) != MAPI_E_SUCCESS)
706 FolderId = mapi_object_get_id(obj_folder);
707 OPENCHANGE_RETVAL_IF(!FolderId, MAPI_E_INVALID_PARAMETER, NULL);
709 mem_ctx = talloc_named(NULL, 0, "GetOwningServers");
713 /* Fill the GetOwningServers operation */
714 request.FolderId = FolderId;
715 size += sizeof (uint64_t);
717 /* Fill the MAPI_REQ request */
718 mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ);
719 mapi_req->opnum = op_MAPI_GetOwningServers;
720 mapi_req->logon_id = logon_id;
721 mapi_req->handle_idx = 0;
722 mapi_req->u.mapi_GetOwningServers = request;
725 /* Fill the mapi_request structure */
726 mapi_request = talloc_zero(mem_ctx, struct mapi_request);
727 mapi_request->mapi_len = size + sizeof (uint32_t);
728 mapi_request->length = size;
729 mapi_request->mapi_req = mapi_req;
730 mapi_request->handles = talloc_array(mem_ctx, uint32_t, 1);
731 mapi_request->handles[0] = mapi_object_get_handle(obj_store);
733 status = emsmdb_transaction_wrapper(session, mem_ctx, mapi_request, &mapi_response);
734 OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx);
735 OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx);
736 retval = mapi_response->mapi_repl->error_code;
737 OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
739 OPENCHANGE_CHECK_NOTIFICATION(session, mapi_response);
741 /* Retrieve GetOwningServers response */
742 response = mapi_response->mapi_repl->u.mapi_GetOwningServers;
744 *OwningServersCount = response.OwningServersCount;
745 *CheapServersCount = response.CheapServersCount;
746 if (*OwningServersCount) {
747 OwningServers = talloc_array((TALLOC_CTX *)session, char *, *OwningServersCount + 1);
748 for (i = 0; i != *OwningServersCount; i++) {
749 OwningServers[i] = talloc_strdup((TALLOC_CTX *)OwningServers, response.OwningServers[i]);
751 OwningServers[i] = NULL;
753 OwningServers = NULL;
756 talloc_free(mapi_response);
757 talloc_free(mem_ctx);
759 return MAPI_E_SUCCESS;
764 \details Gets the current store state for the logged in user
766 This operation must be performed against a user store (not against
767 a Public Folder store). The StoreState will have the
768 STORE_HAS_SEARCHES flag set if there are any active search folders.
769 There are (currently) no other flags in the StoreState.
771 \param obj_store the store object
772 \param StoreState pointer to the store state returned by the server
774 \return MAPI_E_SUCCESS on success, otherwise MAPI error.
776 \note Developers may also call GetLastError() to retrieve the last
777 MAPI error code. Possible MAPI error codes are:
778 - MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized
779 - MAPI_E_INVALID_PARAMETER: obj_store or StoreState are not valid
780 - MAPI_E_CALL_FAILED: A network problem was encountered during the
783 _PUBLIC_ enum MAPISTATUS GetStoreState(mapi_object_t *obj_store,
784 uint32_t *StoreState)
786 struct mapi_request *mapi_request;
787 struct mapi_response *mapi_response;
788 struct EcDoRpc_MAPI_REQ *mapi_req;
789 struct mapi_session *session;
791 enum MAPISTATUS retval;
797 OPENCHANGE_RETVAL_IF(!obj_store, MAPI_E_INVALID_PARAMETER, NULL);
798 OPENCHANGE_RETVAL_IF(!StoreState, MAPI_E_INVALID_PARAMETER, NULL);
800 session = mapi_object_get_session(obj_store);
801 OPENCHANGE_RETVAL_IF(!session, MAPI_E_INVALID_PARAMETER, NULL);
803 if ((retval = mapi_object_get_logon_id(obj_store, &logon_id)) != MAPI_E_SUCCESS)
806 mem_ctx = talloc_named(NULL, 0, "GetStoreState");
809 /* Fill the MAPI_REQ request */
810 mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ);
811 mapi_req->opnum = op_MAPI_GetStoreState;
812 mapi_req->logon_id = logon_id;
813 mapi_req->handle_idx = 0;
816 /* Fill the mapi_request structure */
817 mapi_request = talloc_zero(mem_ctx, struct mapi_request);
818 mapi_request->mapi_len = size + sizeof (uint32_t);
819 mapi_request->length = size;
820 mapi_request->mapi_req = mapi_req;
821 mapi_request->handles = talloc_array(mem_ctx, uint32_t, 1);
822 mapi_request->handles[0] = mapi_object_get_handle(obj_store);
824 status = emsmdb_transaction_wrapper(session, mem_ctx, mapi_request, &mapi_response);
825 OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx);
826 OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx);
827 retval = mapi_response->mapi_repl->error_code;
828 OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
830 OPENCHANGE_CHECK_NOTIFICATION(session, mapi_response);
832 /* Retrieve the StoreState */
833 *StoreState = mapi_response->mapi_repl->u.mapi_GetStoreState.StoreState;
835 talloc_free(mapi_response);
836 talloc_free(mem_ctx);
838 return MAPI_E_SUCCESS;
843 \details Retrieves the sending folder (OUTBOX) for a given store
845 This function obtains the folder that was established as the
846 destination for outgoing messages of a specified message class.
848 This function does not result in any network traffic.
850 \param obj_store the store to get the outbox folder for
851 \param outbox_id the resulting folder identification
853 \return MAPI_E_SUCCESS on success, otherwise MAPI error.
855 \note Developers may also call GetLastError() to retrieve the last
856 MAPI error code. Possible MAPI error codes are:
857 - MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized
858 - MAPI_E_CALL_FAILED: A network problem was encountered during the
861 \sa MAPIInitialize, OpenMsgStore, GetLastError, GetDefaultFolder
863 _PUBLIC_ enum MAPISTATUS GetOutboxFolder(mapi_object_t *obj_store,
864 mapi_id_t *outbox_id)
866 OPENCHANGE_RETVAL_IF(!obj_store, MAPI_E_INVALID_PARAMETER, NULL);
868 *outbox_id = ((mapi_object_store_t *)obj_store->private_data)->fid_outbox;
870 return MAPI_E_SUCCESS;
875 \details Notify the store of a new message to be processed
877 \param obj_store the store that the message is in (logon object)
878 \param obj_folder the folder that the message is in
879 \param obj_msg the message to be processed
880 \param MessageClass the message class of the message to be processed
881 \param MessageFlags the message flags on the message
883 \return MAPI_E_SUCCESS on success, otherwise MAPI error.
885 \note Developers may also call GetLastError() to retrieve the last
886 MAPI error code. Possible MAPI error codes are:
887 - MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized
888 - MAPI_E_INVALID_PARAMETER: one the parameters is invalid
889 - MAPI_E_CALL_FAILED: A network problem was encountered during the
892 \sa GetReceiveFolder, GetReceiveFolderTable
894 _PUBLIC_ enum MAPISTATUS TransportNewMail(mapi_object_t *obj_store, mapi_object_t *obj_folder,
895 mapi_object_t *obj_msg,
896 const char *MessageClass, uint32_t MessageFlags)
898 struct mapi_request *mapi_request;
899 struct mapi_response *mapi_response;
900 struct EcDoRpc_MAPI_REQ *mapi_req;
901 struct TransportNewMail_req request;
902 struct mapi_session *session;
904 enum MAPISTATUS retval;
910 OPENCHANGE_RETVAL_IF(!obj_store, MAPI_E_INVALID_PARAMETER, NULL);
911 OPENCHANGE_RETVAL_IF(!obj_store, MAPI_E_INVALID_PARAMETER, NULL);
912 OPENCHANGE_RETVAL_IF(!obj_folder, MAPI_E_INVALID_PARAMETER, NULL);
913 OPENCHANGE_RETVAL_IF(!obj_msg, MAPI_E_INVALID_PARAMETER, NULL);
914 OPENCHANGE_RETVAL_IF(!MessageClass, MAPI_E_INVALID_PARAMETER, NULL);
915 session = mapi_object_get_session(obj_folder);
916 OPENCHANGE_RETVAL_IF(!session, MAPI_E_INVALID_PARAMETER, NULL);
918 if ((retval = mapi_object_get_logon_id(obj_folder, &logon_id)) != MAPI_E_SUCCESS)
921 mem_ctx = talloc_named(NULL, 0, "TransportNewMail");
923 /* Fill the TransportNewMail operation */
925 request.MessageId = mapi_object_get_id(obj_msg);
926 size += sizeof (uint64_t);
927 request.FolderId = mapi_object_get_id(obj_folder);
928 size += sizeof (uint64_t);
929 request.MessageClass = MessageClass;
930 size += strlen(MessageClass) + 1;
931 request.MessageFlags = MessageFlags;
932 size += sizeof(uint32_t);
934 /* Fill the MAPI_REQ request */
935 mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ);
936 mapi_req->opnum = op_MAPI_TransportNewMail;
937 mapi_req->logon_id = logon_id;
938 mapi_req->handle_idx = 0;
939 mapi_req->u.mapi_TransportNewMail = request;
942 /* Fill the mapi_request structure */
943 mapi_request = talloc_zero(mem_ctx, struct mapi_request);
944 mapi_request->mapi_len = size + sizeof (uint32_t);
945 mapi_request->length = size;
946 mapi_request->mapi_req = mapi_req;
947 mapi_request->handles = talloc_array(mem_ctx, uint32_t, 1);
948 mapi_request->handles[0] = mapi_object_get_handle(obj_store);
950 status = emsmdb_transaction_wrapper(session, mem_ctx, mapi_request, &mapi_response);
951 OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx);
952 OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx);
953 retval = mapi_response->mapi_repl->error_code;
954 OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
956 talloc_free(mapi_response);
957 talloc_free(mem_ctx);
959 return MAPI_E_SUCCESS;