server: intialize aux_header buffer to null if the data is missing.
[tridge/openchange.git] / branches / plugfest / libmapi / mapi_object.c
1 /*
2    OpenChange MAPI implementation.
3
4    Copyright (C) Fabien Le Mentec 2007.
5    Copyright (C) Julien Kerihuel 2007-2011.
6
7    This program is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 3 of the License, or
10    (at your option) any later version.
11    
12    This program is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16    
17    You should have received a copy of the GNU General Public License
18    along with this program.  If not, see <http://www.gnu.org/licenses/>.
19  */
20
21 #include "libmapi/libmapi.h"
22 #include "libmapi/libmapi_private.h"
23
24 /**
25    \file mapi_object.c
26
27    \brief mapi_object_t support functions
28 */
29
30
31 /* FIXME: mapi_object functions should return error codes */
32
33
34 /**
35    keep intern to this file
36 */
37 #define INVALID_HANDLE_VALUE 0xffffffff
38
39
40 /**
41    \details Reset a MAPI object structure
42
43    \param obj pointer on the MAPI object to reset
44  */
45 static void mapi_object_reset(mapi_object_t *obj)
46 {
47         obj->handle = INVALID_HANDLE_VALUE;
48         obj->logon_id = 0;
49         obj->store = false;
50         obj->id = 0;
51         obj->session = NULL;
52         obj->private_data = NULL;
53 }
54
55
56 /**
57    \details Initialize MAPI object
58
59    This function is required to be called before any 
60    manipulation of this MAPI object.
61
62    \param obj the object to initialize
63    
64    \return MAPI_E_SUCCESS on success, otherwise MAPI error.
65    
66    \note Developers may also call GetLastError() to retrieve the last
67    MAPI error code. Possible MAPI error codes are:
68    - MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized.
69
70    \sa mapi_object_release
71 */
72 _PUBLIC_ enum MAPISTATUS mapi_object_init(mapi_object_t *obj)
73 {
74         mapi_object_reset(obj);
75
76         return MAPI_E_SUCCESS;
77 }
78
79
80 /**
81    \details Release MAPI object
82
83    This function is required to be called when this MAPI object
84    is no longer required.
85
86    \param obj pointer on the MAPI object to release
87
88    \sa mapi_object_initialize, Release
89 */
90 _PUBLIC_ void mapi_object_release(mapi_object_t *obj)
91 {
92         enum MAPISTATUS retval;
93
94         if (!obj) return;
95         if (obj->handle == INVALID_HANDLE_VALUE) return;
96
97         retval = Release(obj);
98         if (retval == MAPI_E_SUCCESS) {
99                 if (obj->private_data) {
100                         talloc_free(obj->private_data);
101                 }
102
103                 if (obj->store == true && obj->session) {
104                         obj->session->logon_ids[obj->logon_id] = 0;
105                 }
106
107                 mapi_object_reset(obj);
108         }
109 }
110
111
112 /**
113    \details Check if the supplied object has a valid handle
114
115    \param obj pointer on the MAPI object to test
116
117    \return 0 on success, otherwise 1
118  */
119 int mapi_object_is_invalid(mapi_object_t *obj)
120 {
121         if (mapi_object_get_handle(obj) == INVALID_HANDLE_VALUE) {
122                 return 1;
123         }
124         
125         return MAPI_E_SUCCESS;
126 }
127
128
129 /**
130    \details Copy MAPI object
131
132    This function copies mapi_object data from source to destination.
133
134    \param dst pointer on the destination MAPI object
135    \param src pointer on the source MAPI object
136
137    \return MAPI_E_SUCCESS on success, otherwise MAPI_E_NOT_INITIALIZED
138
139  */
140 _PUBLIC_ enum MAPISTATUS mapi_object_copy(mapi_object_t *dst, mapi_object_t *src)
141 {
142         mapi_object_reset(dst);
143
144         OPENCHANGE_RETVAL_IF(!dst || !src, MAPI_E_NOT_INITIALIZED, NULL);
145
146         dst->id = src->id;
147         dst->handle = src->handle;
148         dst->private_data = src->private_data;
149         dst->logon_id = src->logon_id;
150         dst->session = src->session;
151
152         return MAPI_E_SUCCESS;
153 }
154
155
156 /**
157    \details Retrieve the session associated to the MAPI object
158
159    \param obj the object to get the session for
160
161    \return pointer on a MAPI session on success, otherwise NULL
162  */
163 _PUBLIC_ struct mapi_session *mapi_object_get_session(mapi_object_t *obj)
164 {
165         if (!obj) return NULL;
166         if (!obj->session) return NULL;
167
168         return obj->session;
169 }
170
171
172 /**
173    \details Set the session for a given MAPI object
174
175    \param obj pointer on the object to set the session for
176    \param session pointer on the MAPI session to associate to the MAPI
177    object
178  */
179 _PUBLIC_ void mapi_object_set_session(mapi_object_t *obj, 
180                                       struct mapi_session *session)
181 {
182         if (obj) {
183                 obj->session = session;
184         }
185 }
186
187
188 /**
189    \details Retrieve an object ID for a given MAPI object
190  
191    \param obj pointer on the MAPI object to get the ID for
192
193    \return the object ID, or 0xFFFFFFFFFFFFFFFF if the object does not exist
194 */
195 _PUBLIC_ mapi_id_t mapi_object_get_id(mapi_object_t *obj)
196 {
197         return (!obj) ? -1 : obj->id;
198 }
199
200
201 /**
202    \details Set the id for a given MAPI object
203
204    \param obj pointer on the MAPI object to set the session for
205    \param id Identifier to set to the object obj
206  */
207 void mapi_object_set_id(mapi_object_t *obj, mapi_id_t id)
208 {
209         obj->id = id;
210 }
211
212
213 /**
214    \details Set the logon id for a given MAPI object
215
216    \param obj pointer to the object to set the logon id for
217    \param logon_id the logon identifier to associate to the MAPI
218    object
219  */
220 _PUBLIC_ void mapi_object_set_logon_id(mapi_object_t *obj, 
221                                        uint8_t logon_id)
222 {
223         if (obj) {
224                 obj->logon_id = logon_id;
225         }
226 }
227
228
229 /**
230    \details Retrieve the logon id for a given MAPI object
231
232    \param obj pointer to the object to retrieve the logon id from
233    \param logon_id pointer to a variable to store the logon id
234
235    \return MAPI_E_SUCCESS on success, otherwise MAPI error.
236  */
237 _PUBLIC_ enum MAPISTATUS mapi_object_get_logon_id(mapi_object_t *obj, uint8_t *logon_id)
238 {
239         if (!obj || !logon_id)
240                 return MAPI_E_INVALID_PARAMETER;
241
242         *logon_id = obj->logon_id; 
243
244         return MAPI_E_SUCCESS;
245 }
246
247
248 /**
249    \details Mark a MAPI object as a store object
250    
251    \param obj pointer to the object to set the store boolean for
252  */
253 _PUBLIC_ void mapi_object_set_logon_store(mapi_object_t *obj)
254 {
255         if (obj) {
256                 obj->store = true;
257         }
258 }
259
260
261 /**
262    \details Retrieve the handle associated to a MAPI object
263
264    \param obj pointer on the MAPI object to retrieve the handle from
265
266    \return a valid MAPI object handle on success, otherwise 0xFFFFFFFF.
267  */
268 mapi_handle_t mapi_object_get_handle(mapi_object_t *obj)
269 {
270         return (!obj) ? 0xFFFFFFFF : obj->handle;
271 }
272
273
274 /**
275    \details Associate a handle to a MAPI object
276
277    \param obj pointer on the MAPI object on which handle has to be set
278    \param handle the MAPI handle value
279  */
280 void mapi_object_set_handle(mapi_object_t *obj, mapi_handle_t handle)
281 {
282         obj->handle = handle;
283 }
284
285
286 /**
287    \details Dump a MAPI object (for debugging)
288
289    \param obj pointer on the MAPI object to dump out
290 */
291 _PUBLIC_ void mapi_object_debug(mapi_object_t *obj)
292 {
293         DEBUG(0, ("mapi_object {\n"));
294         DEBUG(0, (" .handle == 0x%x\n", obj->handle));
295         DEBUG(0, (" .id     == 0x%"PRIx64"\n", obj->id));
296         DEBUG(0, ("};\n"));
297 }
298
299
300 /**
301    \details Initialize MAPI object private data to store a MAPI object
302    table
303
304    \param mem_ctx pointer on the memory context
305    \param obj_table pointer on the MAPI object
306  */
307 void mapi_object_table_init(TALLOC_CTX *mem_ctx, mapi_object_t *obj_table)
308 {
309         mapi_object_table_t     *table = NULL;
310
311         if (obj_table->private_data == NULL) {
312                 obj_table->private_data = talloc_zero((TALLOC_CTX *)mem_ctx, mapi_object_table_t);
313         }
314
315         table = (mapi_object_table_t *) obj_table->private_data;
316
317         if (table->bookmark == NULL) {
318                 table->bookmark = talloc_zero((TALLOC_CTX *)table, mapi_object_bookmark_t);
319         }
320
321
322         table->proptags.aulPropTag = 0;
323         table->proptags.cValues = 0;
324         /* start bookmark index after BOOKMARK_END */ 
325         table->bk_last = 3;
326 }
327
328
329 /**
330    \details Fetch a bookmark within a MAPI object table
331
332    \param obj_table pointer on the MAPI object table
333    \param bkPosition the bookmark position to find
334    \param bin pointer on the Sbinary_short the function fills
335
336    \return MAPI_E_SUCCESS on success, otherwise MAPI error.
337  */
338 enum MAPISTATUS mapi_object_bookmark_find(mapi_object_t *obj_table, uint32_t bkPosition,
339                                           struct SBinary_short *bin)
340 {
341         mapi_object_table_t     *table;
342         mapi_object_bookmark_t  *bookmark;
343
344         table = (mapi_object_table_t *)obj_table->private_data;
345         bookmark = table->bookmark;
346
347         /* Sanity checks */
348         OPENCHANGE_RETVAL_IF(!obj_table, MAPI_E_INVALID_PARAMETER, NULL);
349         OPENCHANGE_RETVAL_IF(!table, MAPI_E_NOT_INITIALIZED, NULL);
350         OPENCHANGE_RETVAL_IF(!bookmark, MAPI_E_NOT_INITIALIZED, NULL);
351         OPENCHANGE_RETVAL_IF(bkPosition > table->bk_last, MAPI_E_INVALID_BOOKMARK, NULL);
352         
353         while (bookmark) {
354                 if (bookmark->index == bkPosition) {
355                         bin->cb = bookmark->bin.cb;
356                         bin->lpb = bookmark->bin.lpb;
357                         return MAPI_E_SUCCESS;
358                 }
359                 bookmark = bookmark->next;
360         }
361         return MAPI_E_INVALID_BOOKMARK;
362 }
363
364
365 /**
366    \details Retrieve the number of bookmarks stored in a MAPI object table
367
368    \param obj_table pointer to the MAPI object table
369    \param count pointer to the number of bookmarks to return
370
371    \return MAPI_E_SUCCESS on success, otherwise MAPI error.
372  */
373 _PUBLIC_ enum MAPISTATUS mapi_object_bookmark_get_count(mapi_object_t *obj_table, 
374                                                         uint32_t *count)
375 {
376         mapi_object_table_t     *table;
377
378         table = (mapi_object_table_t *)obj_table->private_data;
379
380         /* Sanity checks */
381         OPENCHANGE_RETVAL_IF(!obj_table, MAPI_E_INVALID_PARAMETER, NULL);
382         OPENCHANGE_RETVAL_IF(!table, MAPI_E_NOT_INITIALIZED, NULL);
383
384         *count = table->bk_last - 3;
385
386         return MAPI_E_SUCCESS;
387 }
388
389
390 /**
391    \details Dump bookmarks associated to a MAPI object table
392
393    \param obj_table pointer on the MAPI object table
394
395    \return MAPI_E_SUCCESS on success, otherwise MAPI error.
396  */
397 _PUBLIC_ enum MAPISTATUS mapi_object_bookmark_debug(mapi_object_t *obj_table)
398 {
399         mapi_object_table_t     *table;
400         mapi_object_bookmark_t  *bookmark;
401
402         table = (mapi_object_table_t *)obj_table->private_data;
403         bookmark = table->bookmark;
404
405         /* Sanity checks */
406         OPENCHANGE_RETVAL_IF(!obj_table, MAPI_E_INVALID_PARAMETER, NULL);
407         OPENCHANGE_RETVAL_IF(!table, MAPI_E_NOT_INITIALIZED, NULL);
408         OPENCHANGE_RETVAL_IF(!bookmark, MAPI_E_NOT_INITIALIZED, NULL);
409         
410         while (bookmark) {
411                 DEBUG(0, ("mapi_object_bookmark {\n"));
412                 DEBUG(0, (".index == %u\n", bookmark->index));
413                 dump_data(0, bookmark->bin.lpb, bookmark->bin.cb);
414                 DEBUG(0, ("};\n"));
415
416                 bookmark = bookmark->next;
417         }       
418         return MAPI_E_SUCCESS;
419 }