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/proto_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
, mapi_id_t id_folder
,
49 mapi_object_t
*obj_folder
)
51 struct mapi_request
*mapi_request
;
52 struct mapi_response
*mapi_response
;
53 struct EcDoRpc_MAPI_REQ
*mapi_req
;
54 struct OpenFolder_req request
;
55 struct mapi_session
*session
;
57 enum MAPISTATUS retval
;
63 OPENCHANGE_RETVAL_IF(!global_mapi_ctx
, MAPI_E_NOT_INITIALIZED
, NULL
);
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(session
->emsmdb
->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(!global_mapi_ctx
, MAPI_E_NOT_INITIALIZED
, NULL
);
152 OPENCHANGE_RETVAL_IF(!obj_store
, MAPI_E_INVALID_PARAMETER
, NULL
);
153 OPENCHANGE_RETVAL_IF(!obj_folder
, MAPI_E_INVALID_PARAMETER
, NULL
);
155 session
[0] = mapi_object_get_session(obj_store
);
156 session
[1] = mapi_object_get_session(obj_folder
);
157 OPENCHANGE_RETVAL_IF(!session
[0], MAPI_E_INVALID_PARAMETER
, NULL
);
158 OPENCHANGE_RETVAL_IF(!session
[1], MAPI_E_INVALID_PARAMETER
, NULL
);
159 OPENCHANGE_RETVAL_IF(session
[0] != session
[1], MAPI_E_INVALID_PARAMETER
, NULL
);
161 if ((retval
= mapi_object_get_logon_id(obj_store
, &logon_id
)) != MAPI_E_SUCCESS
)
164 folderId
= mapi_object_get_id(obj_folder
);
165 OPENCHANGE_RETVAL_IF(!folderId
, MAPI_E_INVALID_PARAMETER
, NULL
);
167 mem_ctx
= talloc_named(NULL
, 0, "PublicFolderIsGhosted");
170 /* Fill the PublicFolderIsGhosted operation */
171 request
.FolderId
= folderId
;
172 size
+= sizeof (uint64_t);
174 /* Fill the MAPI_REQ request */
175 mapi_req
= talloc_zero(mem_ctx
, struct EcDoRpc_MAPI_REQ
);
176 mapi_req
->opnum
= op_MAPI_PublicFolderIsGhosted
;
177 mapi_req
->logon_id
= logon_id
;
178 mapi_req
->handle_idx
= 0;
179 mapi_req
->u
.mapi_PublicFolderIsGhosted
= request
;
182 /* Fill the mapi_request structure */
183 mapi_request
= talloc_zero(mem_ctx
, struct mapi_request
);
184 mapi_request
->mapi_len
= size
+ sizeof (uint32_t);
185 mapi_request
->length
= size
;
186 mapi_request
->mapi_req
= mapi_req
;
187 mapi_request
->handles
= talloc_array(mem_ctx
, uint32_t, 1);
188 mapi_request
->handles
[0] = mapi_object_get_handle(obj_store
);
190 status
= emsmdb_transaction(session
[0]->emsmdb
->ctx
, mapi_request
, &mapi_response
);
191 OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status
), MAPI_E_CALL_FAILED
, mem_ctx
);
192 OPENCHANGE_RETVAL_IF(!mapi_response
->mapi_repl
, MAPI_E_CALL_FAILED
, mem_ctx
);
193 retval
= mapi_response
->mapi_repl
->error_code
;
194 OPENCHANGE_RETVAL_IF(retval
, retval
, mem_ctx
);
196 OPENCHANGE_CHECK_NOTIFICATION(session
[0], mapi_response
);
198 *IsGhosted
= mapi_response
->mapi_repl
->u
.mapi_PublicFolderIsGhosted
.IsGhosted
;
200 talloc_free(mapi_response
);
201 talloc_free(mem_ctx
);
203 return MAPI_E_SUCCESS
;
208 \details Open a NNTP Public Folder given its name
210 \param obj_folder the parent folder
211 \param obj_child the resulting open folder
212 \param name the folder name
214 \return MAPI_E_SUCCESS on success, otherwise MAPI error.
216 \note Developers may also call GetLastError() to retrieve the last
217 MAPI error code. Possible MAPI error codes are:
218 - MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized
219 - MAPI_E_CALL_FAILED: A network problem was encountered during the
224 _PUBLIC_
enum MAPISTATUS
OpenPublicFolderByName(mapi_object_t
*obj_folder
,
225 mapi_object_t
*obj_child
,
228 struct mapi_request
*mapi_request
;
229 struct mapi_response
*mapi_response
;
230 struct EcDoRpc_MAPI_REQ
*mapi_req
;
231 struct OpenPublicFolderByName_req request
;
232 struct mapi_session
*session
;
234 enum MAPISTATUS retval
;
240 OPENCHANGE_RETVAL_IF(!global_mapi_ctx
, MAPI_E_NOT_INITIALIZED
, NULL
);
241 OPENCHANGE_RETVAL_IF(!obj_folder
, MAPI_E_INVALID_PARAMETER
, NULL
);
242 OPENCHANGE_RETVAL_IF(!obj_child
, MAPI_E_INVALID_PARAMETER
, NULL
);
243 OPENCHANGE_RETVAL_IF(!name
, MAPI_E_INVALID_PARAMETER
, NULL
);
244 session
= mapi_object_get_session(obj_folder
);
245 OPENCHANGE_RETVAL_IF(!session
, MAPI_E_INVALID_PARAMETER
, NULL
);
247 if ((retval
= mapi_object_get_logon_id(obj_folder
, &logon_id
)) != MAPI_E_SUCCESS
)
250 mem_ctx
= talloc_named(NULL
, 0, "OpenPublicFolderByName");
253 /* Fill the OpenPublicFolderByName operation */
254 request
.handle_idx
= 0x1;
255 size
+= sizeof (uint8_t);
257 /* name is prefixed with 32 bit [size] */
259 size
+= strlen(name
) + 1 + sizeof (uint32_t);
261 /* Fill the MAPI_REQ request */
262 mapi_req
= talloc_zero(mem_ctx
, struct EcDoRpc_MAPI_REQ
);
263 mapi_req
->opnum
= op_MAPI_OpenPublicFolderByName
;
264 mapi_req
->logon_id
= logon_id
;
265 mapi_req
->handle_idx
= 0;
266 mapi_req
->u
.mapi_OpenPublicFolderByName
= request
;
269 /* Fill the mapi_request structure */
270 mapi_request
= talloc_zero(mem_ctx
, struct mapi_request
);
271 mapi_request
->mapi_len
= size
+ sizeof (uint32_t) * 2;
272 mapi_request
->length
= size
;
273 mapi_request
->mapi_req
= mapi_req
;
274 mapi_request
->handles
= talloc_array(mem_ctx
, uint32_t, 2);
275 mapi_request
->handles
[0] = mapi_object_get_handle(obj_folder
);
276 mapi_request
->handles
[1] = 0xffffffff;
278 status
= emsmdb_transaction(session
->emsmdb
->ctx
, mapi_request
, &mapi_response
);
279 OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status
), MAPI_E_CALL_FAILED
, mem_ctx
);
280 OPENCHANGE_RETVAL_IF(!mapi_response
->mapi_repl
, MAPI_E_CALL_FAILED
, mem_ctx
);
281 retval
= mapi_response
->mapi_repl
->error_code
;
282 OPENCHANGE_RETVAL_IF(retval
, retval
, mem_ctx
);
284 OPENCHANGE_CHECK_NOTIFICATION(session
, mapi_response
);
286 /* Set object session and handle */
287 mapi_object_set_session(obj_child
, session
);
288 mapi_object_set_handle(obj_child
, mapi_response
->handles
[1]);
289 mapi_object_set_logon_id(obj_child
, logon_id
);
291 talloc_free(mapi_response
);
292 talloc_free(mem_ctx
);
294 return MAPI_E_SUCCESS
;
299 \details Sets a folder as the destination for incoming messages of
300 a particular message class.
302 \param obj_store the store to set the receive folder for
303 \param obj_folder the destination folder
304 \param lpszMessageClass the message class the folder will receive
306 \return MAPI_E_SUCCESS on success, otherwise MAPI error.
308 \note Developers may also call GetLastError() to retrieve the last
309 MAPI error code. Possible MAPI error codes are:
310 - MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized
311 - MAPI_E_CALL_FAILED: A network problem was encountered during the
314 \sa GetReceiveFolder, GetReceiveFolderTable
316 _PUBLIC_
enum MAPISTATUS
SetReceiveFolder(mapi_object_t
*obj_store
,
317 mapi_object_t
*obj_folder
,
318 const char *lpszMessageClass
)
320 struct mapi_request
*mapi_request
;
321 struct mapi_response
*mapi_response
;
322 struct EcDoRpc_MAPI_REQ
*mapi_req
;
323 struct SetReceiveFolder_req request
;
324 struct mapi_session
*session
;
326 enum MAPISTATUS retval
;
332 OPENCHANGE_RETVAL_IF(!global_mapi_ctx
, MAPI_E_NOT_INITIALIZED
, NULL
);
333 OPENCHANGE_RETVAL_IF(!obj_store
, MAPI_E_INVALID_PARAMETER
, NULL
);
334 OPENCHANGE_RETVAL_IF(!obj_folder
, MAPI_E_INVALID_PARAMETER
, NULL
);
335 OPENCHANGE_RETVAL_IF(!lpszMessageClass
, MAPI_E_INVALID_PARAMETER
, NULL
);
336 session
= mapi_object_get_session(obj_store
);
337 OPENCHANGE_RETVAL_IF(!session
, MAPI_E_INVALID_PARAMETER
, NULL
);
338 if ((retval
= mapi_object_get_logon_id(obj_store
, &logon_id
)) != MAPI_E_SUCCESS
)
341 mem_ctx
= talloc_named(NULL
, 0, "SetReceiveFolder");
343 /* Fill the SetReceiveFolder operation */
345 request
.fid
= mapi_object_get_id(obj_folder
);
346 size
+= sizeof (uint64_t);
347 request
.lpszMessageClass
= lpszMessageClass
;
348 size
+= strlen(lpszMessageClass
) + 1;
350 /* Fill the MAPI_REQ request */
351 mapi_req
= talloc_zero(mem_ctx
, struct EcDoRpc_MAPI_REQ
);
352 mapi_req
->opnum
= op_MAPI_SetReceiveFolder
;
353 mapi_req
->logon_id
= logon_id
;
354 mapi_req
->handle_idx
= 0;
355 mapi_req
->u
.mapi_SetReceiveFolder
= request
;
358 /* Fill the mapi_request structure */
359 mapi_request
= talloc_zero(mem_ctx
, struct mapi_request
);
360 mapi_request
->mapi_len
= size
+ sizeof (uint32_t);
361 mapi_request
->length
= size
;
362 mapi_request
->mapi_req
= mapi_req
;
363 mapi_request
->handles
= talloc_array(mem_ctx
, uint32_t, 1);
364 mapi_request
->handles
[0] = mapi_object_get_handle(obj_store
);
366 status
= emsmdb_transaction(session
->emsmdb
->ctx
, mapi_request
, &mapi_response
);
367 OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status
), MAPI_E_CALL_FAILED
, mem_ctx
);
368 OPENCHANGE_RETVAL_IF(!mapi_response
->mapi_repl
, MAPI_E_CALL_FAILED
, mem_ctx
);
369 retval
= mapi_response
->mapi_repl
->error_code
;
370 OPENCHANGE_RETVAL_IF(retval
, retval
, mem_ctx
);
372 OPENCHANGE_CHECK_NOTIFICATION(session
, mapi_response
);
374 talloc_free(mapi_response
);
375 talloc_free(mem_ctx
);
377 return MAPI_E_SUCCESS
;
382 \details Gets the receive folder for incoming messages of a
383 particular message class.
385 This function obtains the folder that was established as the
386 destination for incoming messages of a specified message class, or
387 the default receive folder for the message store.
389 \param obj_store the store to get the receiver folder for
390 \param id_folder the resulting folder identification
391 \param MessageClass which message class to find the receivefolder
394 \return MAPI_E_SUCCESS on success, otherwise MAPI error.
396 \note Developers may also call GetLastError() to retrieve the last
397 MAPI error code. Possible MAPI error codes are:
398 - MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized
399 - MAPI_E_CALL_FAILED: A network problem was encountered during the
402 \sa MAPIInitialize, OpenMsgStore, GetLastError, SetReceiveFolder,
403 GetReceiveFolderTable
405 _PUBLIC_
enum MAPISTATUS
GetReceiveFolder(mapi_object_t
*obj_store
,
406 mapi_id_t
*id_folder
,
407 const char *MessageClass
)
409 struct mapi_request
*mapi_request
;
410 struct mapi_response
*mapi_response
;
411 struct EcDoRpc_MAPI_REQ
*mapi_req
;
412 struct GetReceiveFolder_req request
;
413 struct mapi_session
*session
;
415 enum MAPISTATUS retval
;
421 OPENCHANGE_RETVAL_IF(!global_mapi_ctx
, MAPI_E_NOT_INITIALIZED
, NULL
);
422 OPENCHANGE_RETVAL_IF(!obj_store
, MAPI_E_INVALID_PARAMETER
, NULL
);
423 session
= mapi_object_get_session(obj_store
);
424 OPENCHANGE_RETVAL_IF(!session
, MAPI_E_INVALID_PARAMETER
, NULL
);
425 if ((retval
= mapi_object_get_logon_id(obj_store
, &logon_id
)) != MAPI_E_SUCCESS
)
428 mem_ctx
= talloc_named(NULL
, 0, "GetReceiveFolder");
432 /* Fill the GetReceiveFolder operation */
434 request
.MessageClass
= "";
437 request
.MessageClass
= MessageClass
;
438 size
+= strlen (MessageClass
) + 1;
441 /* Fill the MAPI_REQ request */
442 mapi_req
= talloc_zero(mem_ctx
, struct EcDoRpc_MAPI_REQ
);
443 mapi_req
->opnum
= op_MAPI_GetReceiveFolder
;
444 mapi_req
->logon_id
= logon_id
;
445 mapi_req
->handle_idx
= 0;
446 mapi_req
->u
.mapi_GetReceiveFolder
= request
;
449 /* Fill the mapi_request structure */
450 mapi_request
= talloc_zero(mem_ctx
, struct mapi_request
);
451 mapi_request
->mapi_len
= size
+ sizeof (uint32_t);
452 mapi_request
->length
= size
;
453 mapi_request
->mapi_req
= mapi_req
;
454 mapi_request
->handles
= talloc_array(mem_ctx
, uint32_t, 1);
455 mapi_request
->handles
[0] = mapi_object_get_handle(obj_store
);
457 status
= emsmdb_transaction(session
->emsmdb
->ctx
, mapi_request
, &mapi_response
);
458 OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status
), MAPI_E_CALL_FAILED
, mem_ctx
);
459 OPENCHANGE_RETVAL_IF(!mapi_response
->mapi_repl
, MAPI_E_CALL_FAILED
, mem_ctx
);
460 retval
= mapi_response
->mapi_repl
->error_code
;
461 OPENCHANGE_RETVAL_IF(retval
, retval
, mem_ctx
);
463 OPENCHANGE_CHECK_NOTIFICATION(session
, mapi_response
);
465 *id_folder
= mapi_response
->mapi_repl
->u
.mapi_GetReceiveFolder
.folder_id
;
467 talloc_free(mapi_response
);
468 talloc_free(mem_ctx
);
470 return MAPI_E_SUCCESS
;
475 \details Retrieve the receive folder table which includes all the
476 information about the receive folders for the message store
478 \param obj_store the message store object
479 \param SRowSet pointer on a SRowSet structure with
480 GetReceiveFolderTable results.
482 Developers are required to call MAPIFreeBuffer(SRowSet.aRow) when
483 they don't need the folder table data anymore.
485 \return MAPI_E_SUCCESS on success, otherwise MAPI error.
487 \note Developers may also call GetLastError() to retrieve the last
488 MAPI error code. Possible MAPI error codes are:
489 - MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized
490 - MAPI_E_CALL_FAILED: A network problem was encountered during the
493 \sa GetReceiveFolder, SetReceiveFolder
495 _PUBLIC_
enum MAPISTATUS
GetReceiveFolderTable(mapi_object_t
*obj_store
,
496 struct SRowSet
*SRowSet
)
498 struct mapi_request
*mapi_request
;
499 struct mapi_response
*mapi_response
;
500 struct EcDoRpc_MAPI_REQ
*mapi_req
;
501 struct GetReceiveFolderTable_repl
*reply
;
502 struct mapi_session
*session
;
504 enum MAPISTATUS retval
;
511 OPENCHANGE_RETVAL_IF(!global_mapi_ctx
, MAPI_E_NOT_INITIALIZED
, NULL
);
512 OPENCHANGE_RETVAL_IF(!obj_store
, MAPI_E_INVALID_PARAMETER
, NULL
);
513 session
= mapi_object_get_session(obj_store
);
514 OPENCHANGE_RETVAL_IF(!session
, MAPI_E_INVALID_PARAMETER
, NULL
);
515 if ((retval
= mapi_object_get_logon_id(obj_store
, &logon_id
)) != MAPI_E_SUCCESS
)
518 mem_ctx
= talloc_named(NULL
, 0, "GetReceiveFolderTable");
521 /* Fill the MAPI_REQ request */
522 mapi_req
= talloc_zero(mem_ctx
, struct EcDoRpc_MAPI_REQ
);
523 mapi_req
->opnum
= op_MAPI_GetReceiveFolderTable
;
524 mapi_req
->logon_id
= logon_id
;
525 mapi_req
->handle_idx
= 0;
528 /* Fill the mapi_request structure */
529 mapi_request
= talloc_zero(mem_ctx
, struct mapi_request
);
530 mapi_request
->mapi_len
= size
+ sizeof (uint32_t);
531 mapi_request
->length
= size
;
532 mapi_request
->mapi_req
= mapi_req
;
533 mapi_request
->handles
= talloc_array(mem_ctx
, uint32_t, 1);
534 mapi_request
->handles
[0] = mapi_object_get_handle(obj_store
);
536 status
= emsmdb_transaction(session
->emsmdb
->ctx
, mapi_request
, &mapi_response
);
537 OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status
), MAPI_E_CALL_FAILED
, mem_ctx
);
538 OPENCHANGE_RETVAL_IF(!mapi_response
->mapi_repl
, MAPI_E_CALL_FAILED
, mem_ctx
);
539 retval
= mapi_response
->mapi_repl
->error_code
;
540 OPENCHANGE_RETVAL_IF(retval
, retval
, mem_ctx
);
542 OPENCHANGE_CHECK_NOTIFICATION(session
, mapi_response
);
544 reply
= &mapi_response
->mapi_repl
->u
.mapi_GetReceiveFolderTable
;
546 /* Retrieve the ReceiveFolderTable entries */
547 SRowSet
->cRows
= reply
->cValues
;
548 SRowSet
->aRow
= talloc_array((TALLOC_CTX
*)session
, struct SRow
, reply
->cValues
);
550 for (i
= 0; i
< reply
->cValues
; i
++) {
551 SRowSet
->aRow
[i
].ulAdrEntryPad
= 0;
552 SRowSet
->aRow
[i
].cValues
= 3;
553 SRowSet
->aRow
[i
].lpProps
= talloc_array((TALLOC_CTX
*)SRowSet
->aRow
, struct SPropValue
,
554 SRowSet
->aRow
[i
].cValues
);
556 SRowSet
->aRow
[i
].lpProps
[0].ulPropTag
= PR_FID
;
557 SRowSet
->aRow
[i
].lpProps
[0].dwAlignPad
= 0x0;
558 SRowSet
->aRow
[i
].lpProps
[0].value
.d
= reply
->entries
[i
].fid
;
560 if (reply
->entries
[i
].lpszMessageClass
&& strlen(reply
->entries
[i
].lpszMessageClass
)) {
561 SRowSet
->aRow
[i
].lpProps
[1].ulPropTag
= PR_MESSAGE_CLASS
;
562 SRowSet
->aRow
[i
].lpProps
[1].dwAlignPad
= 0x0;
563 SRowSet
->aRow
[i
].lpProps
[1].value
.lpszA
= talloc_strdup((TALLOC_CTX
*)SRowSet
->aRow
[i
].lpProps
, reply
->entries
[i
].lpszMessageClass
);
565 SRowSet
->aRow
[i
].lpProps
[1].ulPropTag
= PR_MESSAGE_CLASS
;
566 SRowSet
->aRow
[i
].lpProps
[1].dwAlignPad
= 0x0;
567 SRowSet
->aRow
[i
].lpProps
[1].value
.lpszA
= "";
570 SRowSet
->aRow
[i
].lpProps
[2].ulPropTag
= PR_LAST_MODIFICATION_TIME
;
571 SRowSet
->aRow
[i
].lpProps
[2].dwAlignPad
= 0x0;
572 SRowSet
->aRow
[i
].lpProps
[2].value
.ft
.dwLowDateTime
= reply
->entries
[i
].modiftime
.dwLowDateTime
;
573 SRowSet
->aRow
[i
].lpProps
[2].value
.ft
.dwHighDateTime
= reply
->entries
[i
].modiftime
.dwHighDateTime
;
576 talloc_free(mapi_response
);
577 talloc_free(mem_ctx
);
579 return MAPI_E_SUCCESS
;
584 \details Retrieves the folder ID of the temporary transport folder.
586 \param obj_store the server object
587 \param FolderId pointer on the returning Folder identifier
589 \return MAPI_E_SUCCESS on success, otherwise MAPI error.
591 \note Developers may also call GetLastError() to retrieve the last
592 MAPI error code. Possible MAPI error codes are:
593 - MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized
594 - MAPI_E_CALL_FAILED: A network problem was encountered during the
597 _PUBLIC_
enum MAPISTATUS
GetTransportFolder(mapi_object_t
*obj_store
,
600 struct mapi_request
*mapi_request
;
601 struct mapi_response
*mapi_response
;
602 struct EcDoRpc_MAPI_REQ
*mapi_req
;
603 struct GetTransportFolder_repl
*reply
;
604 struct mapi_session
*session
;
606 enum MAPISTATUS retval
;
612 OPENCHANGE_RETVAL_IF(!global_mapi_ctx
, MAPI_E_NOT_INITIALIZED
, NULL
);
613 OPENCHANGE_RETVAL_IF(!obj_store
, MAPI_E_INVALID_PARAMETER
, NULL
);
614 OPENCHANGE_RETVAL_IF(!FolderId
, MAPI_E_INVALID_PARAMETER
, NULL
);
615 session
= mapi_object_get_session(obj_store
);
616 OPENCHANGE_RETVAL_IF(!session
, MAPI_E_INVALID_PARAMETER
, NULL
);
617 if ((retval
= mapi_object_get_logon_id(obj_store
, &logon_id
)) != MAPI_E_SUCCESS
)
620 mem_ctx
= talloc_named(NULL
, 0, "GetTransportFolder");
623 /* Fill the MAPI_REQ request */
624 mapi_req
= talloc_zero(mem_ctx
, struct EcDoRpc_MAPI_REQ
);
625 mapi_req
->opnum
= op_MAPI_GetTransportFolder
;
626 mapi_req
->logon_id
= logon_id
;
627 mapi_req
->handle_idx
= 0;
630 /* Fill the mapi_request structure */
631 mapi_request
= talloc_zero(mem_ctx
, struct mapi_request
);
632 mapi_request
->mapi_len
= size
+ sizeof (uint32_t);
633 mapi_request
->length
= size
;
634 mapi_request
->mapi_req
= mapi_req
;
635 mapi_request
->handles
= talloc_array(mem_ctx
, uint32_t, 1);
636 mapi_request
->handles
[0] = mapi_object_get_handle(obj_store
);
638 status
= emsmdb_transaction(session
->emsmdb
->ctx
, mapi_request
, &mapi_response
);
639 OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status
), MAPI_E_CALL_FAILED
, mem_ctx
);
640 OPENCHANGE_RETVAL_IF(!mapi_response
->mapi_repl
, MAPI_E_CALL_FAILED
, mem_ctx
);
641 retval
= mapi_response
->mapi_repl
->error_code
;
642 OPENCHANGE_RETVAL_IF(retval
, retval
, mem_ctx
);
644 OPENCHANGE_CHECK_NOTIFICATION(session
, mapi_response
);
646 /* Retrieve the FolderId parameter */
647 reply
= &mapi_response
->mapi_repl
->u
.mapi_GetTransportFolder
;
648 *FolderId
= reply
->FolderId
;
650 talloc_free(mapi_response
);
651 talloc_free(mem_ctx
);
653 return MAPI_E_SUCCESS
;
658 \details Get the list of servers that host replicas of a given
661 \param obj_store the public folder store object
662 \param obj_folder the folder object we search replica for
663 \param OwningServersCount number of OwningServers
664 \param CheapServersCount number of low-cost servers
665 \param OwningServers pointer on the list of NULL terminated ASCII
666 string representing replica servers
668 \return MAPI_E_SUCCESS on success, otherwise MAPI error.
670 \note ecNoReplicaAvailable (0x469) can be returned if no replica is
671 available for the folder.
673 Developers may also call GetLastError() to retrieve the last
674 MAPI error code. Possible MAPI error codes are:
675 - MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized
676 - MAPI_E_CALL_FAILED: A network problem was encountered during the
679 _PUBLIC_
enum MAPISTATUS
GetOwningServers(mapi_object_t
*obj_store
,
680 mapi_object_t
*obj_folder
,
681 uint16_t *OwningServersCount
,
682 uint16_t *CheapServersCount
,
683 char **OwningServers
)
685 struct mapi_request
*mapi_request
;
686 struct mapi_response
*mapi_response
;
687 struct EcDoRpc_MAPI_REQ
*mapi_req
;
688 struct GetOwningServers_req request
;
689 struct GetOwningServers_repl response
;
690 struct mapi_session
*session
;
692 enum MAPISTATUS retval
;
700 OPENCHANGE_RETVAL_IF(!global_mapi_ctx
, MAPI_E_NOT_INITIALIZED
, NULL
);
701 OPENCHANGE_RETVAL_IF(!obj_store
, MAPI_E_INVALID_PARAMETER
, NULL
);
702 OPENCHANGE_RETVAL_IF(!obj_folder
, MAPI_E_INVALID_PARAMETER
, NULL
);
703 OPENCHANGE_RETVAL_IF(!OwningServersCount
, MAPI_E_INVALID_PARAMETER
, NULL
);
704 OPENCHANGE_RETVAL_IF(!CheapServersCount
, MAPI_E_INVALID_PARAMETER
, NULL
);
705 OPENCHANGE_RETVAL_IF(!OwningServers
, MAPI_E_INVALID_PARAMETER
, NULL
);
707 session
= mapi_object_get_session(obj_store
);
708 OPENCHANGE_RETVAL_IF(!session
, MAPI_E_INVALID_PARAMETER
, NULL
);
710 if ((retval
= mapi_object_get_logon_id(obj_store
, &logon_id
)) != MAPI_E_SUCCESS
)
713 FolderId
= mapi_object_get_id(obj_folder
);
714 OPENCHANGE_RETVAL_IF(!FolderId
, MAPI_E_INVALID_PARAMETER
, NULL
);
716 mem_ctx
= talloc_named(NULL
, 0, "GetOwningServers");
720 /* Fill the GetOwningServers operation */
721 request
.FolderId
= FolderId
;
722 size
+= sizeof (uint64_t);
724 /* Fill the MAPI_REQ request */
725 mapi_req
= talloc_zero(mem_ctx
, struct EcDoRpc_MAPI_REQ
);
726 mapi_req
->opnum
= op_MAPI_GetOwningServers
;
727 mapi_req
->logon_id
= logon_id
;
728 mapi_req
->handle_idx
= 0;
729 mapi_req
->u
.mapi_GetOwningServers
= request
;
732 /* Fill the mapi_request structure */
733 mapi_request
= talloc_zero(mem_ctx
, struct mapi_request
);
734 mapi_request
->mapi_len
= size
+ sizeof (uint32_t);
735 mapi_request
->length
= size
;
736 mapi_request
->mapi_req
= mapi_req
;
737 mapi_request
->handles
= talloc_array(mem_ctx
, uint32_t, 1);
738 mapi_request
->handles
[0] = mapi_object_get_handle(obj_store
);
740 status
= emsmdb_transaction(session
->emsmdb
->ctx
, mapi_request
, &mapi_response
);
741 OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status
), MAPI_E_CALL_FAILED
, mem_ctx
);
742 OPENCHANGE_RETVAL_IF(!mapi_response
->mapi_repl
, MAPI_E_CALL_FAILED
, mem_ctx
);
743 retval
= mapi_response
->mapi_repl
->error_code
;
744 OPENCHANGE_RETVAL_IF(retval
, retval
, mem_ctx
);
746 OPENCHANGE_CHECK_NOTIFICATION(session
, mapi_response
);
748 /* Retrieve GetOwningServers response */
749 response
= mapi_response
->mapi_repl
->u
.mapi_GetOwningServers
;
751 *OwningServersCount
= response
.OwningServersCount
;
752 *CheapServersCount
= response
.CheapServersCount
;
753 if (*OwningServersCount
) {
754 OwningServers
= talloc_array((TALLOC_CTX
*)session
, char *, *OwningServersCount
+ 1);
755 for (i
= 0; i
!= *OwningServersCount
; i
++) {
756 OwningServers
[i
] = talloc_strdup((TALLOC_CTX
*)OwningServers
, response
.OwningServers
[i
]);
758 OwningServers
[i
] = NULL
;
760 OwningServers
= NULL
;
763 talloc_free(mapi_response
);
764 talloc_free(mem_ctx
);
766 return MAPI_E_SUCCESS
;
771 \details Gets the current store state for the logged in user
773 This operation must be performed against a user store (not against
774 a Public Folder store). The StoreState will have the
775 STORE_HAS_SEARCHES flag set if there are any active search folders.
776 There are (currently) no other flags in the StoreState.
778 \param obj_store the store object
779 \param StoreState pointer to the store state returned by the server
781 \return MAPI_E_SUCCESS on success, otherwise MAPI error.
783 \note Developers may also call GetLastError() to retrieve the last
784 MAPI error code. Possible MAPI error codes are:
785 - MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized
786 - MAPI_E_INVALID_PARAMETER: obj_store or StoreState are not valid
787 - MAPI_E_CALL_FAILED: A network problem was encountered during the
790 _PUBLIC_
enum MAPISTATUS
GetStoreState(mapi_object_t
*obj_store
,
791 uint32_t *StoreState
)
793 struct mapi_request
*mapi_request
;
794 struct mapi_response
*mapi_response
;
795 struct EcDoRpc_MAPI_REQ
*mapi_req
;
796 struct mapi_session
*session
;
798 enum MAPISTATUS retval
;
804 OPENCHANGE_RETVAL_IF(!global_mapi_ctx
, MAPI_E_NOT_INITIALIZED
, NULL
);
805 OPENCHANGE_RETVAL_IF(!obj_store
, MAPI_E_INVALID_PARAMETER
, NULL
);
806 OPENCHANGE_RETVAL_IF(!StoreState
, MAPI_E_INVALID_PARAMETER
, NULL
);
808 session
= mapi_object_get_session(obj_store
);
809 OPENCHANGE_RETVAL_IF(!session
, MAPI_E_INVALID_PARAMETER
, NULL
);
811 if ((retval
= mapi_object_get_logon_id(obj_store
, &logon_id
)) != MAPI_E_SUCCESS
)
814 mem_ctx
= talloc_named(NULL
, 0, "GetStoreState");
817 /* Fill the MAPI_REQ request */
818 mapi_req
= talloc_zero(mem_ctx
, struct EcDoRpc_MAPI_REQ
);
819 mapi_req
->opnum
= op_MAPI_GetStoreState
;
820 mapi_req
->logon_id
= logon_id
;
821 mapi_req
->handle_idx
= 0;
824 /* Fill the mapi_request structure */
825 mapi_request
= talloc_zero(mem_ctx
, struct mapi_request
);
826 mapi_request
->mapi_len
= size
+ sizeof (uint32_t);
827 mapi_request
->length
= size
;
828 mapi_request
->mapi_req
= mapi_req
;
829 mapi_request
->handles
= talloc_array(mem_ctx
, uint32_t, 1);
830 mapi_request
->handles
[0] = mapi_object_get_handle(obj_store
);
832 status
= emsmdb_transaction(session
->emsmdb
->ctx
, mapi_request
, &mapi_response
);
833 OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status
), MAPI_E_CALL_FAILED
, mem_ctx
);
834 OPENCHANGE_RETVAL_IF(!mapi_response
->mapi_repl
, MAPI_E_CALL_FAILED
, mem_ctx
);
835 retval
= mapi_response
->mapi_repl
->error_code
;
836 OPENCHANGE_RETVAL_IF(retval
, retval
, mem_ctx
);
838 OPENCHANGE_CHECK_NOTIFICATION(session
, mapi_response
);
840 /* Retrieve the StoreState */
841 *StoreState
= mapi_response
->mapi_repl
->u
.mapi_GetStoreState
.StoreState
;
843 talloc_free(mapi_response
);
844 talloc_free(mem_ctx
);
846 return MAPI_E_SUCCESS
;
851 \details Retrieves the sending folder (OUTBOX) for a given store
853 This function obtains the folder that was established as the
854 destination for outgoing messages of a specified message class.
856 This function does not result in any network traffic.
858 \param obj_store the store to get the outbox folder for
859 \param outbox_id the resulting folder identification
861 \return MAPI_E_SUCCESS on success, otherwise MAPI error.
863 \note Developers may also call GetLastError() to retrieve the last
864 MAPI error code. Possible MAPI error codes are:
865 - MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized
866 - MAPI_E_CALL_FAILED: A network problem was encountered during the
869 \sa MAPIInitialize, OpenMsgStore, GetLastError, GetDefaultFolder
871 _PUBLIC_
enum MAPISTATUS
GetOutboxFolder(mapi_object_t
*obj_store
,
872 mapi_id_t
*outbox_id
)
874 OPENCHANGE_RETVAL_IF(!global_mapi_ctx
, MAPI_E_NOT_INITIALIZED
, NULL
);
875 OPENCHANGE_RETVAL_IF(!obj_store
, MAPI_E_INVALID_PARAMETER
, NULL
);
877 *outbox_id
= ((mapi_object_store_t
*)obj_store
->private_data
)->fid_outbox
;
879 return MAPI_E_SUCCESS
;
884 \details Notify the store of a new message to be processed
886 \param obj_folder the folder that the message is in
887 \param obj_msg the message to be processed
888 \param MessageClass the message class of the message to be processed
889 \param MessageFlags the message flags on the message
891 \return MAPI_E_SUCCESS on success, otherwise MAPI error.
893 \note Developers may also call GetLastError() to retrieve the last
894 MAPI error code. Possible MAPI error codes are:
895 - MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized
896 - MAPI_E_INVALID_PARAMETER: one the parameters is invalid
897 - MAPI_E_CALL_FAILED: A network problem was encountered during the
900 \sa GetReceiveFolder, GetReceiveFolderTable
902 _PUBLIC_
enum MAPISTATUS
TransportNewMail(mapi_object_t
*obj_folder
, mapi_object_t
*obj_msg
,
903 const char *MessageClass
, uint32_t MessageFlags
)
905 struct mapi_request
*mapi_request
;
906 struct mapi_response
*mapi_response
;
907 struct EcDoRpc_MAPI_REQ
*mapi_req
;
908 struct TransportNewMail_req request
;
909 struct mapi_session
*session
;
911 enum MAPISTATUS retval
;
917 OPENCHANGE_RETVAL_IF(!global_mapi_ctx
, MAPI_E_NOT_INITIALIZED
, NULL
);
918 OPENCHANGE_RETVAL_IF(!obj_folder
, MAPI_E_INVALID_PARAMETER
, NULL
);
919 OPENCHANGE_RETVAL_IF(!obj_msg
, MAPI_E_INVALID_PARAMETER
, NULL
);
920 OPENCHANGE_RETVAL_IF(!MessageClass
, MAPI_E_INVALID_PARAMETER
, NULL
);
921 session
= mapi_object_get_session(obj_folder
);
922 OPENCHANGE_RETVAL_IF(!session
, MAPI_E_INVALID_PARAMETER
, NULL
);
924 if ((retval
= mapi_object_get_logon_id(obj_folder
, &logon_id
)) != MAPI_E_SUCCESS
)
927 mem_ctx
= talloc_named(NULL
, 0, "TransportNewMail");
929 /* Fill the TransportNewMail operation */
931 request
.MessageId
= mapi_object_get_id(obj_msg
);
932 size
+= sizeof (uint64_t);
933 request
.FolderId
= mapi_object_get_id(obj_folder
);
934 size
+= sizeof (uint64_t);
935 request
.MessageClass
= MessageClass
;
936 size
+= strlen(MessageClass
) + 1;
937 request
.MessageFlags
= MessageFlags
;
938 size
+= sizeof(uint32_t);
940 /* Fill the MAPI_REQ request */
941 mapi_req
= talloc_zero(mem_ctx
, struct EcDoRpc_MAPI_REQ
);
942 mapi_req
->opnum
= op_MAPI_TransportNewMail
;
943 mapi_req
->logon_id
= logon_id
;
944 mapi_req
->handle_idx
= 0;
945 mapi_req
->u
.mapi_TransportNewMail
= request
;
948 /* Fill the mapi_request structure */
949 mapi_request
= talloc_zero(mem_ctx
, struct mapi_request
);
950 mapi_request
->mapi_len
= size
+ sizeof (uint32_t);
951 mapi_request
->length
= size
;
952 mapi_request
->mapi_req
= mapi_req
;
953 mapi_request
->handles
= talloc_array(mem_ctx
, uint32_t, 1);
954 mapi_request
->handles
[0] = mapi_object_get_handle(obj_folder
);
956 status
= emsmdb_transaction(session
->emsmdb
->ctx
, mapi_request
, &mapi_response
);
957 OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status
), MAPI_E_CALL_FAILED
, mem_ctx
);
958 OPENCHANGE_RETVAL_IF(!mapi_response
->mapi_repl
, MAPI_E_CALL_FAILED
, mem_ctx
);
959 retval
= mapi_response
->mapi_repl
->error_code
;
960 OPENCHANGE_RETVAL_IF(retval
, retval
, mem_ctx
);
962 talloc_free(mapi_response
);
963 talloc_free(mem_ctx
);
965 return MAPI_E_SUCCESS
;