Fix OpenChange server code and access to Samba4 databases.
[OpenChange-git-clone.git] / libmapi / IStoreFolder.c
blobd3e46248c6d9fa00a370745b7d676b150b112011
1 /*
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>
24 /**
25 \file IStoreFolder.c
27 \brief Open messages
31 /**
32 \details Opens a specific message and retrieves a MAPI object that
33 can be used to get or set message properties.
35 This function opens a specific message defined by a combination of
36 object store, folder ID, and message ID and which read/write access
37 is defined by ulFlags.
39 \param obj_store the store to read from
40 \param id_folder the folder ID
41 \param id_message the message ID
42 \param obj_message the resulting message object
43 \param ulFlags
45 Possible ulFlags values:
46 - 0x0: read only access
47 - 0x1: ReadWrite
48 - 0x3: Create
50 \return MAPI_E_SUCCESS on success, otherwise MAPI error.
52 \note Developers may also call GetLastError() to retrieve the last
53 MAPI error code. Possible MAPI error codes are:
54 - MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized
55 - MAPI_E_INVALID_PARAMETER: obj_store is undefined
56 - MAPI_E_CALL_FAILED: A network problem was encountered during the
57 transaction
59 \sa MAPIInitialize, GetLastError
61 _PUBLIC_ enum MAPISTATUS OpenMessage(mapi_object_t *obj_store,
62 mapi_id_t id_folder,
63 mapi_id_t id_message,
64 mapi_object_t *obj_message,
65 uint8_t ulFlags)
67 struct mapi_request *mapi_request;
68 struct mapi_response *mapi_response;
69 struct EcDoRpc_MAPI_REQ *mapi_req;
70 struct OpenMessage_req request;
71 struct OpenMessage_repl *reply;
72 struct mapi_session *session;
73 mapi_object_message_t *message;
74 struct SPropValue lpProp;
75 NTSTATUS status;
76 enum MAPISTATUS retval;
77 uint32_t size = 0;
78 TALLOC_CTX *mem_ctx;
79 uint32_t i = 0;
80 uint8_t logon_id;
82 /* Sanity checks */
83 OPENCHANGE_RETVAL_IF(!global_mapi_ctx, MAPI_E_NOT_INITIALIZED, NULL);
84 OPENCHANGE_RETVAL_IF(!obj_store, MAPI_E_INVALID_PARAMETER, NULL);
85 session = mapi_object_get_session(obj_store);
86 OPENCHANGE_RETVAL_IF(!session, MAPI_E_INVALID_PARAMETER, NULL);
88 if ((retval = mapi_object_get_logon_id(obj_store, &logon_id)) != MAPI_E_SUCCESS)
89 return retval;
91 mem_ctx = talloc_named(NULL, 0, "OpenMessage");
93 /* Fill the OpenMessage operation */
94 request.handle_idx = 0x1;
95 request.CodePageId = 0xfff;
96 request.FolderId = id_folder;
97 request.OpenModeFlags = ulFlags;
98 request.MessageId = id_message;
99 size = sizeof (uint8_t) + sizeof(uint16_t) + sizeof(mapi_id_t) + sizeof(uint8_t) + sizeof(mapi_id_t);
101 /* Fill the MAPI_REQ request */
102 mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ);
103 mapi_req->opnum = op_MAPI_OpenMessage;
104 mapi_req->logon_id = logon_id;
105 mapi_req->handle_idx = 0;
106 mapi_req->u.mapi_OpenMessage = request;
107 size += 5;
109 /* Fill the mapi_request structure */
110 mapi_request = talloc_zero(mem_ctx, struct mapi_request);
111 mapi_request->mapi_len = size + sizeof (uint32_t) * 2;
112 mapi_request->length = size;
113 mapi_request->mapi_req = mapi_req;
114 mapi_request->handles = talloc_array(mem_ctx, uint32_t, 2);
115 mapi_request->handles[0] = mapi_object_get_handle(obj_store);
116 mapi_request->handles[1] = 0xffffffff;
118 status = emsmdb_transaction(session->emsmdb->ctx, mapi_request, &mapi_response);
119 OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx);
120 OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx);
121 retval = mapi_response->mapi_repl->error_code;
122 OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
124 OPENCHANGE_CHECK_NOTIFICATION(session, mapi_response);
126 /* Set object session and handle */
127 mapi_object_set_session(obj_message, session);
128 mapi_object_set_handle(obj_message, mapi_response->handles[1]);
129 mapi_object_set_logon_id(obj_message, logon_id);
131 /* Store OpenMessage reply data */
132 reply = &mapi_response->mapi_repl->u.mapi_OpenMessage;
134 message = talloc_zero((TALLOC_CTX *)session, mapi_object_message_t);
135 message->cValues = reply->RecipientColumns.cValues;
136 message->SRowSet.cRows = reply->RowCount;
137 message->SRowSet.aRow = talloc_array((TALLOC_CTX *)message, struct SRow, reply->RowCount + 1);
139 message->SPropTagArray.cValues = reply->RecipientColumns.cValues;
140 message->SPropTagArray.aulPropTag = talloc_steal(message, reply->RecipientColumns.aulPropTag);
142 for (i = 0; i < reply->RowCount; i++) {
143 emsmdb_get_SRow((TALLOC_CTX *)message, global_mapi_ctx->lp_ctx,
144 &(message->SRowSet.aRow[i]), &message->SPropTagArray,
145 reply->recipients[i].RecipientRow.prop_count,
146 &reply->recipients[i].RecipientRow.prop_values,
147 reply->recipients[i].RecipientRow.layout, 1);
149 lpProp.ulPropTag = PR_RECIPIENT_TYPE;
150 lpProp.value.l = reply->recipients[i].RecipClass;
151 SRow_addprop(&(message->SRowSet.aRow[i]), lpProp);
153 lpProp.ulPropTag = PR_INTERNET_CPID;
154 lpProp.value.l = reply->recipients[i].codepage;
155 SRow_addprop(&(message->SRowSet.aRow[i]), lpProp);
158 /* add SPropTagArray elements we automatically append to SRow */
159 SPropTagArray_add((TALLOC_CTX *)message, &message->SPropTagArray, PR_RECIPIENT_TYPE);
160 SPropTagArray_add((TALLOC_CTX *)message, &message->SPropTagArray, PR_INTERNET_CPID);
162 obj_message->private_data = (void *) message;
164 talloc_free(mapi_response);
165 talloc_free(mem_ctx);
167 return MAPI_E_SUCCESS;
171 \details Retrieve the message properties for an already open message.
173 This function is very similar to OpenMessage, but works on an already
174 open message object.
176 \param obj_store the store to read from
177 \param id_folder the folder ID
178 \param id_message the message ID
179 \param obj_message the resulting message object
180 \param ulFlags
182 Possible ulFlags values:
183 - 0x0: read only access
184 - 0x1: ReadWrite
185 - 0x3: Create
187 \return MAPI_E_SUCCESS on success, otherwise MAPI error.
189 \note Developers may also call GetLastError() to retrieve the last
190 MAPI error code. Possible MAPI error codes are:
191 - MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized
192 - MAPI_E_INVALID_PARAMETER: obj_store is undefined
193 - MAPI_E_CALL_FAILED: A network problem was encountered during the
194 transaction
196 \sa OpenMessage
198 _PUBLIC_ enum MAPISTATUS ReloadCachedInformation(mapi_object_t *obj_message)
200 struct mapi_request *mapi_request;
201 struct mapi_response *mapi_response;
202 struct EcDoRpc_MAPI_REQ *mapi_req;
203 struct ReloadCachedInformation_req request;
204 struct ReloadCachedInformation_repl *reply;
205 struct mapi_session *session;
206 mapi_object_message_t *message;
207 struct SPropValue lpProp;
208 NTSTATUS status;
209 enum MAPISTATUS retval;
210 uint32_t size = 0;
211 TALLOC_CTX *mem_ctx;
212 uint32_t i = 0;
213 uint8_t logon_id;
215 /* Sanity checks */
216 OPENCHANGE_RETVAL_IF(!global_mapi_ctx, MAPI_E_NOT_INITIALIZED, NULL);
217 OPENCHANGE_RETVAL_IF(!obj_message, MAPI_E_INVALID_PARAMETER, NULL);
218 session = mapi_object_get_session(obj_message);
219 OPENCHANGE_RETVAL_IF(!session, MAPI_E_INVALID_PARAMETER, NULL);
221 if ((retval = mapi_object_get_logon_id(obj_message, &logon_id)) != MAPI_E_SUCCESS)
222 return retval;
224 mem_ctx = talloc_named(NULL, 0, "ReloadCachedInformation");
226 /* Fill the ReloadCachedInformation operation */
227 request.Reserved = 0x0000;
228 size += sizeof (uint16_t);
230 /* Fill the MAPI_REQ request */
231 mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ);
232 mapi_req->opnum = op_MAPI_ReloadCachedInformation;
233 mapi_req->logon_id = logon_id;
234 mapi_req->handle_idx = 0;
235 mapi_req->u.mapi_ReloadCachedInformation = request;
236 size += 5;
238 /* Fill the mapi_request structure */
239 mapi_request = talloc_zero(mem_ctx, struct mapi_request);
240 mapi_request->mapi_len = size + sizeof (uint32_t);
241 mapi_request->length = size;
242 mapi_request->mapi_req = mapi_req;
243 mapi_request->handles = talloc_array(mem_ctx, uint32_t, 1);
244 mapi_request->handles[0] = mapi_object_get_handle(obj_message);
246 status = emsmdb_transaction(session->emsmdb->ctx, mapi_request, &mapi_response);
247 OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx);
248 OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx);
249 retval = mapi_response->mapi_repl->error_code;
251 OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
253 OPENCHANGE_CHECK_NOTIFICATION(session, mapi_response);
255 /* Store ReloadCachedInformation reply data */
256 reply = &mapi_response->mapi_repl->u.mapi_ReloadCachedInformation;
258 message = talloc_zero((TALLOC_CTX *)session, mapi_object_message_t);
259 message->cValues = reply->RecipientColumns.cValues;
260 message->SRowSet.cRows = reply->RowCount;
261 message->SRowSet.aRow = talloc_array((TALLOC_CTX *)message, struct SRow, reply->RowCount + 1);
263 message->SPropTagArray.cValues = reply->RecipientColumns.cValues;
264 message->SPropTagArray.aulPropTag = talloc_steal(message, reply->RecipientColumns.aulPropTag);
266 for (i = 0; i < reply->RowCount; i++) {
267 emsmdb_get_SRow((TALLOC_CTX *)message, global_mapi_ctx->lp_ctx,
268 &(message->SRowSet.aRow[i]), &message->SPropTagArray,
269 reply->RecipientRows[i].RecipientRow.prop_count,
270 &reply->RecipientRows[i].RecipientRow.prop_values,
271 reply->RecipientRows[i].RecipientRow.layout, 1);
273 lpProp.ulPropTag = PR_RECIPIENT_TYPE;
274 lpProp.value.l = reply->RecipientRows[i].RecipientType;
275 SRow_addprop(&(message->SRowSet.aRow[i]), lpProp);
277 lpProp.ulPropTag = PR_INTERNET_CPID;
278 lpProp.value.l = reply->RecipientRows[i].CodePageId;
279 SRow_addprop(&(message->SRowSet.aRow[i]), lpProp);
282 /* add SPropTagArray elements we automatically append to SRow */
283 SPropTagArray_add((TALLOC_CTX *)message, &message->SPropTagArray, PR_RECIPIENT_TYPE);
284 SPropTagArray_add((TALLOC_CTX *)message, &message->SPropTagArray, PR_INTERNET_CPID);
286 talloc_free(obj_message->private_data);
287 obj_message->private_data = (void *) message;
289 talloc_free(mapi_response);
290 talloc_free(mem_ctx);
292 errno = 0;
293 return MAPI_E_SUCCESS;