25
25
\brief Property and Stream Object routines and Rops
29
#include <sys/types.h>
32
#include "libmapi/libmapi.h"
28
33
#include "mapiproxy/dcesrv_mapiproxy.h"
29
34
#include "mapiproxy/libmapiproxy/libmapiproxy.h"
30
35
#include "mapiproxy/libmapiserver/libmapiserver.h"
31
36
#include "dcesrv_exchange_emsmdb.h"
34
\details Retrieve properties on a mapistore object
36
\param mem_ctx pointer to the memory context
37
\param emsmdbp_ctx pointer to the emsmdb provider context
38
\param request GetProps request
39
\param response pointer to the GetProps reply
40
\param private_data pointer tot eh private data stored for this
43
\note We do not handle anything yet. This is just a skeleton.
45
\return MAPI_E_SUCCESS on success, otherwise MAPI error
47
static enum MAPISTATUS RopGetPropertiesSpecific_mapistore(TALLOC_CTX *mem_ctx,
48
struct emsmdbp_context *emsmdbp_ctx,
49
struct GetProps_req request,
50
struct GetProps_repl *response,
53
enum MAPISTATUS retval;
54
struct emsmdbp_object *object;
55
uint32_t contextID = -1;
58
struct SPropTagArray SPropTagArray;
65
object = (struct emsmdbp_object *) private_data;
67
switch (object->type) {
68
case EMSMDBP_OBJECT_FOLDER:
69
/* contextID = object->object.folder->contextID; */
70
/* fmid = object->object.folder->folderID; */
71
/* type = MAPISTORE_FOLDER; */
73
case EMSMDBP_OBJECT_MESSAGE:
74
contextID = object->object.message->contextID;
75
fmid = object->object.message->messageID;
76
type = MAPISTORE_MESSAGE;
83
SPropTagArray.cValues = request.prop_count;
84
SPropTagArray.aulPropTag = request.properties;
86
/* TODO: Fix contextID signed */
87
if ((int)contextID != -1) {
88
aRow = talloc_zero(mem_ctx, struct SRow);
90
mapistore_getprops(emsmdbp_ctx->mstore_ctx, contextID, fmid, type, &SPropTagArray, aRow);
91
/* Check if we need the layout */
92
for (i = 0; i < request.prop_count; i++) {
93
for (j = 0; j < aRow->cValues; j++) {
94
if (request.properties[i] == aRow->lpProps[j].ulPropTag) {
96
response->layout = 0x0;
100
response->layout = 0x1;
105
for (i = 0; i < request.prop_count; i++) {
106
response->layout = 0x1;
107
data = (void *) find_SPropValue_data(aRow, request.properties[i]);
109
request.properties[i] = (enum MAPITAGS)((int)(request.properties[i] & 0xFFFF0000) + PT_ERROR);
110
retval = MAPI_E_NOT_FOUND;
111
data = (void *)&retval;
113
libmapiserver_push_property(mem_ctx,
114
request.properties[i], (const void *)data,
115
&response->prop_data, response->layout, 0);
119
response->layout = 0x1;
120
for (i = 0; i < request.prop_count; i++) {
121
request.properties[i] = (enum MAPITAGS)((int)(request.properties[i] & 0xFFFF0000) + PT_ERROR);
122
retval = MAPI_E_NOT_FOUND;
123
response->layout = 0x1;
124
data = (void *)&retval;
125
libmapiserver_push_property(mem_ctx,
126
request.properties[i], (const void *)data,
127
&response->prop_data, response->layout, 0);
131
return MAPI_E_SUCCESS;
136
\details Retrieve properties on a mailbox object.
138
\param mem_ctx pointer to the memory context
139
\param emsmdbp_ctx pointer to the emsmdb provider context
140
\param request GetProps request
141
\param response pointer to the GetProps reply
142
\param private_data pointer to the private data stored for this
145
\note Mailbox objects have a limited set of supported properties.
147
\return MAPI_E_SUCCESS on success, otherwise MAPI error
149
static enum MAPISTATUS RopGetPropertiesSpecific_Mailbox(TALLOC_CTX *mem_ctx,
150
struct emsmdbp_context *emsmdbp_ctx,
151
struct GetProps_req request,
152
struct GetProps_repl *response,
155
enum MAPISTATUS retval;
156
struct emsmdbp_object *object;
158
struct SBinary_short bin;
163
OPENCHANGE_RETVAL_IF(!private_data, MAPI_E_INVALID_PARAMETER, NULL);
165
object = (struct emsmdbp_object *) private_data;
167
/* Step 1. Check if we need a layout */
168
response->layout = 0;
169
for (i = 0; i < request.prop_count; i++) {
170
switch (request.properties[i]) {
171
case PR_MAPPING_SIGNATURE:
172
case PR_IPM_PUBLIC_FOLDERS_ENTRYID:
173
response->layout = 0x1;
175
case PR_USER_ENTRYID:
177
case PR_MAILBOX_OWNER_ENTRYID:
178
case PR_MAILBOX_OWNER_NAME:
179
case PR_MAILBOX_OWNER_NAME_UNICODE:
180
if (object->object.mailbox->mailboxstore == false) {
181
response->layout = 0x1;
185
retval = openchangedb_get_folder_property(mem_ctx, emsmdbp_ctx->oc_ctx,
186
emsmdbp_ctx->szDisplayName,
187
request.properties[i],
188
object->object.mailbox->folderID,
191
response->layout = 0x1;
195
if (response->layout == 1) {
200
/* Step 2. Fill the GetProps blob */
201
for (i = 0; i < request.prop_count; i++) {
202
switch (request.properties[i]) {
203
case PR_MAPPING_SIGNATURE:
204
case PR_IPM_PUBLIC_FOLDERS_ENTRYID:
205
error = MAPI_E_NO_ACCESS;
206
request.properties[i] = (enum MAPITAGS)((int)(request.properties[i] & 0xFFFF0000) + PT_ERROR);
207
libmapiserver_push_property(mem_ctx,
208
request.properties[i], (const void *)&error,
209
&response->prop_data, response->layout, 0);
211
case PR_USER_ENTRYID:
212
retval = entryid_set_AB_EntryID(mem_ctx, object->object.mailbox->szUserDN, &bin);
213
libmapiserver_push_property(mem_ctx,
214
request.properties[i], (const void *)&bin,
215
&response->prop_data, response->layout, 0);
216
talloc_free(bin.lpb);
218
case PR_MAILBOX_OWNER_ENTRYID:
219
if (object->object.mailbox->mailboxstore == false) {
220
error = MAPI_E_NO_ACCESS;
221
request.properties[i] = (enum MAPITAGS)((int)(request.properties[i] & 0xFFFF0000) + PT_ERROR);
222
libmapiserver_push_property(mem_ctx,
223
request.properties[i], (const void *)&error,
224
&response->prop_data, response->layout, 0);
226
retval = entryid_set_AB_EntryID(mem_ctx, object->object.mailbox->owner_EssDN,
228
libmapiserver_push_property(mem_ctx,
229
request.properties[i], (const void *)&bin,
230
&response->prop_data, response->layout, 0);
231
talloc_free(bin.lpb);
234
case PR_MAILBOX_OWNER_NAME:
235
case PR_MAILBOX_OWNER_NAME_UNICODE:
236
if (object->object.mailbox->mailboxstore == false) {
237
error = MAPI_E_NO_ACCESS;
238
request.properties[i] = (enum MAPITAGS)((int)(request.properties[i] & 0xFFFF0000) + PT_ERROR);
239
libmapiserver_push_property(mem_ctx,
240
request.properties[i], (const void *)&error,
241
&response->prop_data, response->layout, 0);
243
libmapiserver_push_property(mem_ctx,
244
request.properties[i],
245
(const void *)object->object.mailbox->owner_Name,
246
&response->prop_data, response->layout, 0);
250
retval = openchangedb_get_folder_property(mem_ctx, emsmdbp_ctx->oc_ctx,
251
emsmdbp_ctx->szDisplayName, request.properties[i],
252
object->object.mailbox->folderID, (void **)&data);
254
request.properties[i] = (enum MAPITAGS)((int)(request.properties[i] & 0xFFFF0000) + PT_ERROR);
255
data = (void *)&retval;
257
libmapiserver_push_property(mem_ctx,
258
request.properties[i], (const void *)data,
259
&response->prop_data, response->layout, 0);
264
return MAPI_E_SUCCESS;
269
\details Retrieve properties on a systemfolder object.
271
\param mem_ctx pointer to the memory context
272
\param emsmdbp_ctx pointer to the emsmdb provider context
273
\param request GetProps request
274
\param response pointer to the GetProps reply
275
\param private_data pointer to the private data stored for this
277
\param private_data pointer to the private data stored for this
280
\return MAPI_E_SUCCESS on success, otherwise MAPI error
282
static enum MAPISTATUS RopGetPropertiesSpecific_SystemSpecialFolder(TALLOC_CTX *mem_ctx,
283
struct emsmdbp_context *emsmdbp_ctx,
284
struct GetProps_req request,
285
struct GetProps_repl *response,
288
enum MAPISTATUS retval;
289
struct emsmdbp_object *object;
290
struct emsmdbp_object_folder *folder;
295
OPENCHANGE_RETVAL_IF(!private_data, MAPI_E_INVALID_PARAMETER, NULL);
297
object = (struct emsmdbp_object *) private_data;
298
folder = (struct emsmdbp_object_folder *) object->object.folder;
300
/* Step 1. Lookup properties and set layout */
301
response->layout = 0x0;
302
for (i = 0; i < request.prop_count; i++) {
303
if (openchangedb_lookup_folder_property(emsmdbp_ctx->oc_ctx, request.properties[i],
305
response->layout = 0x1;
310
/* Step 2. Fetch properties values */
311
for (i = 0; i < request.prop_count; i++) {
312
retval = openchangedb_get_folder_property(mem_ctx, emsmdbp_ctx->oc_ctx,
313
emsmdbp_ctx->szDisplayName, request.properties[i],
314
folder->folderID, (void **)&data);
316
request.properties[i] = (enum MAPITAGS)((int)(request.properties[i] & 0xFFFF0000) + PT_ERROR);
317
data = (void *)&retval;
319
libmapiserver_push_property(mem_ctx,
320
request.properties[i], (const void *)data,
321
&response->prop_data, response->layout, 0);
324
return MAPI_E_SUCCESS;
329
39
\details EcDoRpc GetPropertiesSpecific (0x07) Rop. This operation
330
40
retrieves from properties data from specified object.
379
95
handle = handles[mapi_req->handle_idx];
380
96
retval = mapi_handles_search(emsmdbp_ctx->handles_ctx, handle, &rec);
381
if (retval) goto end;
98
mapi_repl->error_code = MAPI_E_NOT_FOUND;
99
DEBUG(5, (" handle (%x) not found: %x\n", handle, mapi_req->handle_idx));
383
103
retval = mapi_handles_get_private_data(rec, &private_data);
385
mapistore = emsmdbp_is_mapistore(rec);
391
/* Temporary hack: If this is a mapistore root container
392
* (e.g. Inbox, Calendar etc.), directly stored under
393
* IPM.Subtree, then fetch properties from openchange
394
* dispatcher db, not mapistore */
395
object = (struct emsmdbp_object *) private_data;
396
if (object && object->type == EMSMDBP_OBJECT_FOLDER &&
397
object->object.folder->mapistore_root == true) {
398
retval = RopGetPropertiesSpecific_SystemSpecialFolder(mem_ctx, emsmdbp_ctx,
399
request, &response, private_data);
403
switch (object->type) {
404
case EMSMDBP_OBJECT_MAILBOX:
405
retval = RopGetPropertiesSpecific_Mailbox(mem_ctx, emsmdbp_ctx, request, &response, private_data);
407
case EMSMDBP_OBJECT_FOLDER:
408
retval = RopGetPropertiesSpecific_SystemSpecialFolder(mem_ctx, emsmdbp_ctx, request, &response, private_data);
104
object = private_data;
106
mapi_repl->error_code = MAPI_E_NOT_FOUND;
107
DEBUG(5, (" object (%x) not found: %x\n", handle, mapi_req->handle_idx));
111
if (!(object->type == EMSMDBP_OBJECT_MAILBOX
112
|| object->type == EMSMDBP_OBJECT_FOLDER
113
|| object->type == EMSMDBP_OBJECT_MESSAGE
114
|| object->type == EMSMDBP_OBJECT_ATTACHMENT)) {
115
mapi_repl->error_code = MAPI_E_INVALID_OBJECT;
116
DEBUG(5, (" GetProperties cannot occur on an object of type '%s' (%d)\n", emsmdbp_getstr_type(object), object->type));
120
properties = talloc_zero(NULL, struct SPropTagArray);
121
properties->cValues = request->prop_count;
122
properties->aulPropTag = talloc_array(properties, enum MAPITAGS, request->prop_count);
123
untyped_status = talloc_array(NULL, bool, request->prop_count);
125
for (i = 0; i < request->prop_count; i++) {
126
properties->aulPropTag[i] = request->properties[i];
127
if ((request->properties[i] & 0xffff) == 0) {
128
properties->aulPropTag[i] |= get_property_type(request->properties[i] >> 16);
129
untyped_status[i] = true;
132
untyped_status[i] = false;
136
data_pointers = emsmdbp_object_get_properties(mem_ctx, emsmdbp_ctx, object, properties, &retvals);
138
for (i = 0; i < request->prop_count; i++) {
139
if (retvals[i] == MAPI_E_SUCCESS) {
140
propType = properties->aulPropTag[i] & 0xffff;
141
if (propType == PT_STRING8) {
142
stream_size = strlen((const char *) data_pointers[i]) + 1;
144
else if (propType == PT_UNICODE) {
145
stream_size = strlen_m_ext((char *) data_pointers[i], CH_UTF8, CH_UTF16LE) * 2 + 2;
147
else if (propType == PT_BINARY) {
148
stream_size = ((struct Binary_r *) data_pointers[i])->cb;
153
if (stream_size > 8192) {
154
DEBUG(5, ("%s: attaching stream data for property %.8x\n", __FUNCTION__, properties->aulPropTag[i]));
155
stream_data = emsmdbp_stream_data_from_value(object, properties->aulPropTag[i], data_pointers[i]);
157
DLIST_ADD(object->stream_data, stream_data);
159
/* This will trigger the opening of a property stream from the client. */
160
retvals[i] = MAPI_E_NOT_ENOUGH_MEMORY;
415
/* folder or messages handled by mapistore */
416
retval = RopGetPropertiesSpecific_mapistore(mem_ctx, emsmdbp_ctx, request, &response, private_data);
421
mapi_repl->error_code = MAPI_E_SUCCESS;
422
mapi_repl->u.mapi_GetProps = response;
164
mapi_repl->error_code = MAPI_E_SUCCESS;
165
emsmdbp_fill_row_blob(mem_ctx,
168
&response->prop_data,
173
talloc_free(data_pointers);
175
talloc_free(properties);
176
talloc_free(retvals);
425
179
*size += libmapiserver_RopGetPropertiesSpecific_size(mapi_req, mapi_repl);
427
181
return MAPI_E_SUCCESS;
185
\details EcDoRpc GetPropertiesAll (0x08) Rop. This operation gets
186
all the property values for an object.
188
\param mem_ctx pointer to the memory context
189
\param emsmdbp_ctx pointer to the emsmdb provider context
190
\param mapi_req pointer to the GetPropertiesAll EcDoRpc_MAPI_REQ
192
\param mapi_repl pointer to the GetPropertiesAll EcDoRpc_MAPI_REPL
194
\param handles pointer to the MAPI handles array
195
\param size pointer to the mapi_response size to update
197
\return MAPI_E_SUCCESS on success, otherwise MAPI error
199
_PUBLIC_ enum MAPISTATUS EcDoRpc_RopGetPropertiesAll(TALLOC_CTX *mem_ctx,
200
struct emsmdbp_context *emsmdbp_ctx,
201
struct EcDoRpc_MAPI_REQ *mapi_req,
202
struct EcDoRpc_MAPI_REPL *mapi_repl,
203
uint32_t *handles, uint16_t *size)
205
enum MAPISTATUS retval;
206
enum MAPISTATUS *retvals = NULL;
207
struct GetPropsAll_repl *response;
209
struct mapi_handles *rec = NULL;
210
void *private_data = NULL;
211
struct emsmdbp_object *object;
212
struct SPropTagArray *SPropTagArray;
213
void **data_pointers;
216
DEBUG(4, ("exchange_emsmdb: [OXCPRPT] GetPropertiesAll (0x08)\n"));
219
OPENCHANGE_RETVAL_IF(!emsmdbp_ctx, MAPI_E_NOT_INITIALIZED, NULL);
220
OPENCHANGE_RETVAL_IF(!mapi_req, MAPI_E_INVALID_PARAMETER, NULL);
221
OPENCHANGE_RETVAL_IF(!mapi_repl, MAPI_E_INVALID_PARAMETER, NULL);
222
OPENCHANGE_RETVAL_IF(!handles, MAPI_E_INVALID_PARAMETER, NULL);
223
OPENCHANGE_RETVAL_IF(!size, MAPI_E_INVALID_PARAMETER, NULL);
225
response = &mapi_repl->u.mapi_GetPropsAll;
227
/* Initialize GetPropsAll response */
228
response->properties.cValues = 0;
229
response->properties.lpProps = NULL;
231
/* Fill EcDoRpc_MAPI_REPL reply */
232
mapi_repl->opnum = mapi_req->opnum;
233
mapi_repl->handle_idx = mapi_req->handle_idx;
234
/* mapi_repl->error_code = MAPI_E_NOT_FOUND; */
235
mapi_repl->error_code = MAPI_E_SUCCESS;
237
handle = handles[mapi_req->handle_idx];
238
retval = mapi_handles_search(emsmdbp_ctx->handles_ctx, handle, &rec);
240
mapi_repl->error_code = MAPI_E_INVALID_OBJECT;
241
DEBUG(5, (" handle (%x) not found: %x\n", handle, mapi_req->handle_idx));
245
retval = mapi_handles_get_private_data(rec, &private_data);
246
object = private_data;
248
mapi_repl->error_code = MAPI_E_INVALID_OBJECT;
249
DEBUG(5, (" object (%x) not found: %x\n", handle, mapi_req->handle_idx));
253
retval = emsmdbp_object_get_available_properties(mem_ctx, emsmdbp_ctx, object, &SPropTagArray);
255
mapi_repl->error_code = MAPI_E_INVALID_OBJECT;
256
DEBUG(5, (" object (%x) not found: %x\n", handle, mapi_req->handle_idx));
260
data_pointers = emsmdbp_object_get_properties(mem_ctx, emsmdbp_ctx, object, SPropTagArray, &retvals);
262
response->properties.lpProps = talloc_array(mem_ctx, struct mapi_SPropValue, 2);
263
response->properties.cValues = 0;
264
for (i = 0; i < SPropTagArray->cValues; i++) {
265
if (retvals[i] == MAPI_E_SUCCESS) {
266
response->properties.lpProps = add_mapi_SPropValue(mem_ctx,
267
response->properties.lpProps,
268
&response->properties.cValues,
269
SPropTagArray->aulPropTag[i],
270
(void *)data_pointers[i]);
277
*size += libmapiserver_RopGetPropertiesAll_size(mapi_repl);
278
return MAPI_E_SUCCESS;
283
\details EcDoRpc GetPropertiesList (0x9) Rop. This operation
284
retrieves the list of MAPI tags for an object.
286
\param mem_ctx pointer to the memory context
287
\param emsmdbp_ctx pointer to the emsmdb provider context
288
\param mapi_req pointer to the SetProperties EcDoRpc_MAPI_REQ
290
\param mapi_repl pointer to the SetProperties EcDoRpc_MAPI_REPL
292
\param handles pointer to the MAPI handles array
293
\param size pointer to the mapi_response size to update
295
\return MAPI_E_SUCCESS on success, otherwise MAPI error
297
_PUBLIC_ enum MAPISTATUS EcDoRpc_RopGetPropertiesList(TALLOC_CTX *mem_ctx,
298
struct emsmdbp_context *emsmdbp_ctx,
299
struct EcDoRpc_MAPI_REQ *mapi_req,
300
struct EcDoRpc_MAPI_REPL *mapi_repl,
301
uint32_t *handles, uint16_t *size)
303
enum MAPISTATUS retval;
304
struct GetPropList_repl *response;
306
struct mapi_handles *rec = NULL;
307
void *private_data = NULL;
308
struct emsmdbp_object *object;
309
struct SPropTagArray *SPropTagArray;
311
DEBUG(4, ("exchange_emsmdb: [OXCPRPT] GetPropertiesList (0x9)\n"));
314
OPENCHANGE_RETVAL_IF(!emsmdbp_ctx, MAPI_E_NOT_INITIALIZED, NULL);
315
OPENCHANGE_RETVAL_IF(!mapi_req, MAPI_E_INVALID_PARAMETER, NULL);
316
OPENCHANGE_RETVAL_IF(!mapi_repl, MAPI_E_INVALID_PARAMETER, NULL);
317
OPENCHANGE_RETVAL_IF(!handles, MAPI_E_INVALID_PARAMETER, NULL);
318
OPENCHANGE_RETVAL_IF(!size, MAPI_E_INVALID_PARAMETER, NULL);
320
response = &mapi_repl->u.mapi_GetPropList;
322
/* Initialize GetPropList response */
324
response->tags = NULL;
326
/* Fill EcDoRpc_MAPI_REPL reply */
327
mapi_repl->opnum = mapi_req->opnum;
328
mapi_repl->handle_idx = mapi_req->handle_idx;
329
mapi_repl->error_code = MAPI_E_SUCCESS;
331
handle = handles[mapi_req->handle_idx];
332
retval = mapi_handles_search(emsmdbp_ctx->handles_ctx, handle, &rec);
334
mapi_repl->error_code = MAPI_E_INVALID_OBJECT;
335
DEBUG(5, (" handle (%x) not found: %x\n", handle, mapi_req->handle_idx));
339
retval = mapi_handles_get_private_data(rec, &private_data);
340
object = private_data;
342
mapi_repl->error_code = MAPI_E_INVALID_OBJECT;
343
DEBUG(5, (" object (%x) not found: %x\n", handle, mapi_req->handle_idx));
347
retval = emsmdbp_object_get_available_properties(mem_ctx, emsmdbp_ctx, object, &SPropTagArray);
349
mapi_repl->error_code = MAPI_E_INVALID_OBJECT;
350
DEBUG(5, (" object (%x) not found: %x\n", handle, mapi_req->handle_idx));
354
response->count = SPropTagArray->cValues;
355
response->tags = SPropTagArray->aulPropTag;
358
*size += libmapiserver_RopGetPropertiesList_size(mapi_repl);
359
return MAPI_E_SUCCESS;
432
363
\details EcDoRpc SetProperties (0x0a) Rop. This operation sets
603
534
mapi_repl->opnum = mapi_req->opnum;
604
535
mapi_repl->error_code = MAPI_E_SUCCESS;
605
mapi_repl->handle_idx = mapi_req->handle_idx;
536
mapi_repl->handle_idx = mapi_req->u.mapi_OpenStream.handle_idx;
606
537
mapi_repl->u.mapi_OpenStream.StreamSize = 0;
608
539
/* Step 1. Retrieve parent handle in the hierarchy */
609
540
handle = handles[mapi_req->handle_idx];
610
541
retval = mapi_handles_search(emsmdbp_ctx->handles_ctx, handle, &parent);
611
OPENCHANGE_RETVAL_IF(retval, retval, NULL);
613
if (!mapi_repl->error_code) {
614
retval = mapi_handles_add(emsmdbp_ctx->handles_ctx, handle, &rec);
615
object = emsmdbp_object_stream_init((TALLOC_CTX *)rec, emsmdbp_ctx,
616
mapi_req->u.mapi_OpenStream.PropertyTag, parent);
619
retval = mapi_handles_set_private_data(rec, object);
622
mapi_repl->handle_idx = mapi_req->u.mapi_OpenStream.handle_idx;
623
handles[mapi_repl->handle_idx] = rec->handle;
543
mapi_repl->error_code = MAPI_E_INVALID_OBJECT;
544
DEBUG(5, (" handle (%x) not found: %x\n", handle, mapi_req->handle_idx));
548
mapi_handles_get_private_data(parent, &data);
549
parent_object = (struct emsmdbp_object *) data;
550
if (!(parent_object->type == EMSMDBP_OBJECT_FOLDER
551
|| parent_object->type == EMSMDBP_OBJECT_MESSAGE
552
|| parent_object->type == EMSMDBP_OBJECT_ATTACHMENT)) {
553
mapi_repl->error_code = MAPI_E_NO_SUPPORT;
557
request = &mapi_req->u.mapi_OpenStream;
559
mode = request->OpenModeFlags;
560
if (mode == OpenStream_BestAccess) {
561
if (parent_object->type == EMSMDBP_OBJECT_MESSAGE) {
562
if (parent_object->object.message->read_write) {
563
mode = OpenStream_ReadWrite;
566
mode = OpenStream_ReadOnly;
570
mode = OpenStream_ReadOnly;
574
if (parent_object->type == EMSMDBP_OBJECT_MESSAGE && !parent_object->object.message->read_write && (mode == OpenStream_ReadWrite || mode == OpenStream_Create)) {
575
mapi_repl->error_code = MAPI_E_NO_ACCESS;
579
if (request->PropertyTag == PidTagSecurityDescriptorAsXml) {
580
/* exception; see oxcperm - 3.1.4.1 Retrieving Folder Permissions */
581
mapi_repl->error_code = MAPI_E_NOT_IMPLEMENTED;
585
/* TODO: implementation status:
586
- OpenStream_ReadOnly (supported)
587
- OpenStream_ReadWrite (supported)
588
- OpenStream_Create (supported)
589
- OpenStream_BestAccess
592
object = emsmdbp_object_stream_init(NULL, emsmdbp_ctx, parent_object);
593
object->object.stream->property = request->PropertyTag;
594
object->object.stream->stream.position = 0;
595
object->object.stream->stream.buffer.length = 0;
597
if (mode == OpenStream_ReadOnly || mode == OpenStream_ReadWrite) {
598
object->object.stream->read_write = (mode == OpenStream_ReadWrite);
599
stream_data = emsmdbp_object_get_stream_data(parent_object, object->object.stream->property);
601
object->object.stream->stream.buffer = stream_data->data;
602
(void) talloc_reference(object->object.stream, object->object.stream->stream.buffer.data);
603
DLIST_REMOVE(parent_object->stream_data, stream_data);
604
talloc_free(stream_data);
607
properties.cValues = 1;
608
properties.aulPropTag = &request->PropertyTag;
610
data_pointers = emsmdbp_object_get_properties(mem_ctx, emsmdbp_ctx, parent_object, &properties, &retvals);
611
if (data_pointers == NULL) {
612
mapi_repl->error_code = MAPI_E_INVALID_OBJECT;
616
if (retvals[0] == MAPI_E_SUCCESS) {
617
stream_data = emsmdbp_stream_data_from_value(data_pointers, request->PropertyTag, data_pointers[0]);
618
object->object.stream->stream.buffer = stream_data->data;
619
(void) talloc_reference(object->object.stream, object->object.stream->stream.buffer.data);
620
talloc_free(data_pointers);
621
talloc_free(retvals);
624
mapi_repl->error_code = retvals[0];
625
talloc_free(data_pointers);
626
talloc_free(retvals);
632
else { /* OpenStream_Create */
633
object->object.stream->read_write = true;
634
object->object.stream->stream.buffer.data = talloc_zero(object->object.stream, uint8_t);
635
object->object.stream->stream.buffer.length = 0;
638
mapi_repl->u.mapi_OpenStream.StreamSize = object->object.stream->stream.buffer.length;
640
retval = mapi_handles_add(emsmdbp_ctx->handles_ctx, handle, &rec);
641
(void) talloc_reference(rec, object);
642
handles[mapi_repl->handle_idx] = rec->handle;
643
mapi_handles_set_private_data(rec, object);
626
647
*size += libmapiserver_RopOpenStream_size(mapi_repl);
628
649
return MAPI_E_SUCCESS;
729
766
mapi_repl->opnum = mapi_req->opnum;
730
767
mapi_repl->error_code = MAPI_E_SUCCESS;
731
768
mapi_repl->handle_idx = mapi_req->handle_idx;
732
mapi_repl->u.mapi_WriteStream.WrittenSize = mapi_req->u.mapi_WriteStream.data.length;
769
mapi_repl->u.mapi_WriteStream.WrittenSize = 0;
734
771
/* Step 1. Retrieve parent handle in the hierarchy */
735
772
handle = handles[mapi_req->handle_idx];
736
773
retval = mapi_handles_search(emsmdbp_ctx->handles_ctx, handle, &parent);
737
if (retval) goto end;
775
mapi_repl->error_code = MAPI_E_INVALID_OBJECT;
776
DEBUG(5, (" handle (%x) not found: %x\n", handle, mapi_req->handle_idx));
739
retval = mapi_handles_get_private_data(rec, &private_data);
780
retval = mapi_handles_get_private_data(parent, &private_data);
740
781
object = (struct emsmdbp_object *) private_data;
741
if (!object || object->type != EMSMDBP_OBJECT_STREAM) goto end;
743
/* TODO effective work goes here */
782
if (!object || object->type != EMSMDBP_OBJECT_STREAM) {
783
mapi_repl->error_code = MAPI_E_INVALID_OBJECT;
784
DEBUG(5, (" invalid object\n"));
788
if (!object->object.stream->read_write) {
789
mapi_repl->error_code = MAPI_E_NO_ACCESS;
793
request = &mapi_req->u.mapi_WriteStream;
794
if (request->data.length > 0) {
795
emsmdbp_stream_write_buffer(object->object.stream, &object->object.stream->stream, request->data);
796
mapi_repl->u.mapi_WriteStream.WrittenSize = request->data.length;
799
object->object.stream->needs_commit = true;
745
801
*size += libmapiserver_RopWriteStream_size(mapi_repl);
747
803
return MAPI_E_SUCCESS;
807
\details EcDoRpc CommitStream (0x5d) Rop.
809
\param mem_ctx pointer to the memory context
810
\param emsmdbp_ctx pointer to the emsmdb provider context
811
\param mapi_req pointer to the DeleteProperties EcDoRpc_MAPI_REQ
813
\param mapi_repl pointer to the DeleteProperties EcDoRpc_MAPI_REPL
815
\param handles pointer to the MAPI handles array
816
\param size pointer to the mapi_response size to update
818
\return MAPI_E_SUCCESS on success, otherwise MAPI error
820
_PUBLIC_ enum MAPISTATUS EcDoRpc_RopCommitStream(TALLOC_CTX *mem_ctx,
821
struct emsmdbp_context *emsmdbp_ctx,
822
struct EcDoRpc_MAPI_REQ *mapi_req,
823
struct EcDoRpc_MAPI_REPL *mapi_repl,
824
uint32_t *handles, uint16_t *size)
826
enum MAPISTATUS retval;
827
struct mapi_handles *rec = NULL;
828
struct emsmdbp_object *object = NULL;
832
DEBUG(4, ("exchange_emsmdb: [OXCPRPT] CommitStream (0x5d)\n"));
835
OPENCHANGE_RETVAL_IF(!emsmdbp_ctx, MAPI_E_NOT_INITIALIZED, NULL);
836
OPENCHANGE_RETVAL_IF(!mapi_req, MAPI_E_INVALID_PARAMETER, NULL);
837
OPENCHANGE_RETVAL_IF(!mapi_repl, MAPI_E_INVALID_PARAMETER, NULL);
838
OPENCHANGE_RETVAL_IF(!handles, MAPI_E_INVALID_PARAMETER, NULL);
839
OPENCHANGE_RETVAL_IF(!size, MAPI_E_INVALID_PARAMETER, NULL);
841
mapi_repl->opnum = mapi_req->opnum;
842
mapi_repl->error_code = MAPI_E_SUCCESS;
843
mapi_repl->handle_idx = mapi_req->handle_idx;
846
/* Step 1. Retrieve parent handle in the hierarchy */
847
handle = handles[mapi_req->handle_idx];
848
retval = mapi_handles_search(emsmdbp_ctx->handles_ctx, handle, &rec);
850
mapi_repl->error_code = MAPI_E_INVALID_OBJECT;
851
DEBUG(5, (" handle (%x) not found: %x\n", handle, mapi_req->handle_idx));
855
retval = mapi_handles_get_private_data(rec, &private_data);
856
object = (struct emsmdbp_object *) private_data;
857
if (!object || object->type != EMSMDBP_OBJECT_STREAM) {
858
mapi_repl->error_code = MAPI_E_INVALID_OBJECT;
859
DEBUG(5, (" invalid object\n"));
863
if (!object->object.stream->read_write) {
864
mapi_repl->error_code = MAPI_E_NO_ACCESS;
868
emsmdbp_object_stream_commit(object);
871
*size += libmapiserver_RopCommitStream_size(mapi_repl);
873
return MAPI_E_SUCCESS;
877
\details EcDoRpc GetStreamSize (0x5e) Rop. This operation returns the
878
number of bytes in a stream.
880
\param mem_ctx pointer to the memory context
881
\param emsmdbp_ctx pointer to the emsmdb provider context
882
\param mapi_req pointer to the WriteStream EcDoRpc_MAPI_REQ
884
\param mapi_repl pointer to the WriteStream EcDoRpc_MAPI_REPL
886
\param handles pointer to the MAPI handles array
887
\param size pointer to the mapi response size to update
889
\return MAPI_E_SUCCESS on success, otherwise MAPI error
891
_PUBLIC_ enum MAPISTATUS EcDoRpc_RopGetStreamSize(TALLOC_CTX *mem_ctx,
892
struct emsmdbp_context *emsmdbp_ctx,
893
struct EcDoRpc_MAPI_REQ *mapi_req,
894
struct EcDoRpc_MAPI_REPL *mapi_repl,
895
uint32_t *handles, uint16_t *size)
897
enum MAPISTATUS retval;
898
struct mapi_handles *parent = NULL;
900
struct emsmdbp_object *object = NULL;
903
DEBUG(4, ("exchange_emsmdb: [OXCPRPT] GetStreamSize (0x5e)\n"));
906
OPENCHANGE_RETVAL_IF(!emsmdbp_ctx, MAPI_E_NOT_INITIALIZED, NULL);
907
OPENCHANGE_RETVAL_IF(!mapi_req, MAPI_E_INVALID_PARAMETER, NULL);
908
OPENCHANGE_RETVAL_IF(!mapi_repl, MAPI_E_INVALID_PARAMETER, NULL);
909
OPENCHANGE_RETVAL_IF(!handles, MAPI_E_INVALID_PARAMETER, NULL);
910
OPENCHANGE_RETVAL_IF(!size, MAPI_E_INVALID_PARAMETER, NULL);
912
mapi_repl->opnum = mapi_req->opnum;
913
mapi_repl->error_code = MAPI_E_SUCCESS;
914
mapi_repl->handle_idx = mapi_req->handle_idx;
916
/* Step 1. Retrieve parent handle in the hierarchy */
917
handle = handles[mapi_req->handle_idx];
918
retval = mapi_handles_search(emsmdbp_ctx->handles_ctx, handle, &parent);
920
mapi_repl->error_code = MAPI_E_INVALID_OBJECT;
921
DEBUG(5, (" handle (%x) not found: %x\n", handle, mapi_req->handle_idx));
925
retval = mapi_handles_get_private_data(parent, &private_data);
926
object = (struct emsmdbp_object *) private_data;
927
if (!object || object->type != EMSMDBP_OBJECT_STREAM) {
928
mapi_repl->error_code = MAPI_E_INVALID_OBJECT;
929
DEBUG(5, (" invalid object\n"));
933
mapi_repl->u.mapi_GetStreamSize.StreamSize = object->object.stream->stream.buffer.length;
936
*size += libmapiserver_RopGetStreamSize_size(mapi_repl);
938
return MAPI_E_SUCCESS;
942
\details EcDoRpc SeekStream (0x2e) Rop. This operation positions the cursor
945
\param mem_ctx pointer to the memory context
946
\param emsmdbp_ctx pointer to the emsmdb provider context
947
\param mapi_req pointer to the WriteStream EcDoRpc_MAPI_REQ
949
\param mapi_repl pointer to the WriteStream EcDoRpc_MAPI_REPL
951
\param handles pointer to the MAPI handles array
952
\param size pointer to the mapi response size to update
954
\return MAPI_E_SUCCESS on success, otherwise MAPI error
956
_PUBLIC_ enum MAPISTATUS EcDoRpc_RopSeekStream(TALLOC_CTX *mem_ctx,
957
struct emsmdbp_context *emsmdbp_ctx,
958
struct EcDoRpc_MAPI_REQ *mapi_req,
959
struct EcDoRpc_MAPI_REPL *mapi_repl,
960
uint32_t *handles, uint16_t *size)
962
enum MAPISTATUS retval;
963
struct mapi_handles *parent = NULL;
965
struct emsmdbp_object *object = NULL;
966
uint32_t handle, new_position;
968
DEBUG(4, ("exchange_emsmdb: [OXCPRPT] SeekStream (0x2e)\n"));
971
OPENCHANGE_RETVAL_IF(!emsmdbp_ctx, MAPI_E_NOT_INITIALIZED, NULL);
972
OPENCHANGE_RETVAL_IF(!mapi_req, MAPI_E_INVALID_PARAMETER, NULL);
973
OPENCHANGE_RETVAL_IF(!mapi_repl, MAPI_E_INVALID_PARAMETER, NULL);
974
OPENCHANGE_RETVAL_IF(!handles, MAPI_E_INVALID_PARAMETER, NULL);
975
OPENCHANGE_RETVAL_IF(!size, MAPI_E_INVALID_PARAMETER, NULL);
977
mapi_repl->opnum = mapi_req->opnum;
978
mapi_repl->error_code = MAPI_E_SUCCESS;
979
mapi_repl->handle_idx = mapi_req->handle_idx;
981
/* Step 1. Retrieve parent handle in the hierarchy */
982
handle = handles[mapi_req->handle_idx];
983
retval = mapi_handles_search(emsmdbp_ctx->handles_ctx, handle, &parent);
985
mapi_repl->error_code = MAPI_E_INVALID_OBJECT;
986
DEBUG(5, (" handle (%x) not found: %x\n", handle, mapi_req->handle_idx));
990
retval = mapi_handles_get_private_data(parent, &private_data);
991
object = (struct emsmdbp_object *) private_data;
992
if (!object || object->type != EMSMDBP_OBJECT_STREAM) {
993
mapi_repl->error_code = MAPI_E_INVALID_OBJECT;
994
DEBUG(5, (" invalid object\n"));
998
switch (mapi_req->u.mapi_SeekStream.Origin) {
999
case 0: /* beginning */
1002
case 1: /* current */
1003
new_position = object->object.stream->stream.position;
1006
new_position = object->object.stream->stream.buffer.length;
1009
mapi_repl->error_code = MAPI_E_INVALID_PARAMETER;
1013
new_position += mapi_req->u.mapi_SeekStream.Offset;
1014
if (new_position < object->object.stream->stream.buffer.length + 1) {
1015
object->object.stream->stream.position = new_position;
1016
mapi_repl->u.mapi_SeekStream.NewPosition = new_position;
1019
mapi_repl->error_code = MAPI_E_DISK_ERROR;
1023
*size += libmapiserver_RopSeekStream_size(mapi_repl);
1025
return MAPI_E_SUCCESS;
1030
\details EcDoRpc SetStreamSize (0x2f) Rop. This operation
1031
copy messages from one folder to another.
1033
\param mem_ctx pointer to the memory context
1034
\param emsmdbp_ctx pointer to the emsmdb provider context
1035
\param mapi_req pointer to the DeleteProperties EcDoRpc_MAPI_REQ
1037
\param mapi_repl pointer to the DeleteProperties EcDoRpc_MAPI_REPL
1039
\param handles pointer to the MAPI handles array
1040
\param size pointer to the mapi_response size to update
1042
\return MAPI_E_SUCCESS on success, otherwise MAPI error
1044
_PUBLIC_ enum MAPISTATUS EcDoRpc_RopSetStreamSize(TALLOC_CTX *mem_ctx,
1045
struct emsmdbp_context *emsmdbp_ctx,
1046
struct EcDoRpc_MAPI_REQ *mapi_req,
1047
struct EcDoRpc_MAPI_REPL *mapi_repl,
1048
uint32_t *handles, uint16_t *size)
1050
enum MAPISTATUS retval;
1051
struct mapi_handles *parent = NULL;
1053
struct emsmdbp_object *object;
1055
struct SetStreamSize_req *request;
1057
DEBUG(4, ("exchange_emsmdb: [OXCPRPT] SetStreamSize (0x2f)\n"));
1060
OPENCHANGE_RETVAL_IF(!emsmdbp_ctx, MAPI_E_NOT_INITIALIZED, NULL);
1061
OPENCHANGE_RETVAL_IF(!mapi_req, MAPI_E_INVALID_PARAMETER, NULL);
1062
OPENCHANGE_RETVAL_IF(!mapi_repl, MAPI_E_INVALID_PARAMETER, NULL);
1063
OPENCHANGE_RETVAL_IF(!handles, MAPI_E_INVALID_PARAMETER, NULL);
1064
OPENCHANGE_RETVAL_IF(!size, MAPI_E_INVALID_PARAMETER, NULL);
1066
mapi_repl->opnum = mapi_req->opnum;
1067
mapi_repl->error_code = MAPI_E_SUCCESS;
1068
mapi_repl->handle_idx = mapi_req->handle_idx;
1069
mapi_repl->u.mapi_WriteStream.WrittenSize = 0;
1071
/* Step 1. Retrieve parent handle in the hierarchy */
1072
handle = handles[mapi_req->handle_idx];
1073
retval = mapi_handles_search(emsmdbp_ctx->handles_ctx, handle, &parent);
1075
mapi_repl->error_code = MAPI_E_INVALID_OBJECT;
1076
DEBUG(5, (" handle (%x) not found: %x\n", handle, mapi_req->handle_idx));
1080
retval = mapi_handles_get_private_data(parent, &private_data);
1081
object = (struct emsmdbp_object *) private_data;
1082
if (!object || object->type != EMSMDBP_OBJECT_STREAM) {
1083
mapi_repl->error_code = MAPI_E_INVALID_OBJECT;
1084
DEBUG(5, (" invalid object\n"));
1088
request = &mapi_req->u.mapi_SetStreamSize;
1089
object->object.stream->stream.buffer.length = request->SizeStream;
1092
*size += libmapiserver_RopSetStreamSize_size(mapi_repl);
1094
return MAPI_E_SUCCESS;
752
1098
\details EcDoRpc GetPropertyIdsFromNames (0x56) Rop. This operation
788
1137
mapi_req->u.mapi_GetIDsFromNames.count);
790
1139
for (i = 0; i < mapi_req->u.mapi_GetIDsFromNames.count; i++) {
791
mapistore_namedprops_get_mapped_id(emsmdbp_ctx->mstore_ctx->mapistore_nprops_ctx,
792
mapi_req->u.mapi_GetIDsFromNames.nameid[i],
793
&mapi_repl->u.mapi_GetIDsFromNames.propID[i]);
1140
ret = mapistore_namedprops_get_mapped_id(emsmdbp_ctx->mstore_ctx->nprops_ctx,
1141
mapi_req->u.mapi_GetIDsFromNames.nameid[i],
1142
&mapi_repl->u.mapi_GetIDsFromNames.propID[i]);
1143
if (ret != MAPISTORE_SUCCESS) {
1144
if (mapi_req->u.mapi_GetIDsFromNames.ulFlags == GetIDsFromNames_GetOrCreate) {
1145
if (!has_transaction) {
1146
has_transaction = true;
1147
ldb_transaction_start(emsmdbp_ctx->mstore_ctx->nprops_ctx);
1148
mapped_id = mapistore_namedprops_next_unused_id(emsmdbp_ctx->mstore_ctx->nprops_ctx);
1149
if (mapped_id == 0) {
1156
mapistore_namedprops_create_id(emsmdbp_ctx->mstore_ctx->nprops_ctx,
1157
mapi_req->u.mapi_GetIDsFromNames.nameid[i],
1159
mapi_repl->u.mapi_GetIDsFromNames.propID[i] = mapped_id;
1162
mapi_repl->u.mapi_GetIDsFromNames.propID[i] = 0x0000;
1163
lpguid = &mapi_req->u.mapi_GetIDsFromNames.nameid[i].lpguid;
1164
DEBUG(5, (" no mapping for property %.8x-%.4x-%.4x-%.2x%.2x-%.2x%.2x%.2x%.2x%.2x%.2x:",
1165
lpguid->time_low, lpguid->time_mid, lpguid->time_hi_and_version,
1166
lpguid->clock_seq[0], lpguid->clock_seq[1],
1167
lpguid->node[0], lpguid->node[1],
1168
lpguid->node[2], lpguid->node[3],
1169
lpguid->node[4], lpguid->node[5]));
1171
if (mapi_req->u.mapi_GetIDsFromNames.nameid[i].ulKind == MNID_ID)
1172
DEBUG(5, ("%.4x\n", mapi_req->u.mapi_GetIDsFromNames.nameid[i].kind.lid));
1173
else if (mapi_req->u.mapi_GetIDsFromNames.nameid[i].ulKind == MNID_STRING)
1174
DEBUG(5, ("%s\n", mapi_req->u.mapi_GetIDsFromNames.nameid[i].kind.lpwstr.Name));
1176
DEBUG(5, ("[invalid ulKind]"));
1178
mapi_repl->error_code = MAPI_W_ERRORS_RETURNED;
1183
if (has_transaction) {
1184
ldb_transaction_commit(emsmdbp_ctx->mstore_ctx->nprops_ctx);
796
1187
*size += libmapiserver_RopGetPropertyIdsFromNames_size(mapi_repl);
798
1189
return MAPI_E_SUCCESS;
1193
\details EcDoRpc GetNamesFromIDs (0x56) Rop. This operation
1194
gets property IDs for specified property names.
1196
\param mem_ctx pointer to the memory context
1197
\param emsmdbp_ctx pointer to the emsmdb provider context
1198
\param mapi_req pointer to the GetNamesFromIDs
1199
EcDoRpc_MAPI_REQ structure
1200
\param mapi_repl pointer to the GetNamesFromIDs
1201
EcDoRpc_MAPI_REPL structure
1202
\param handles pointer to the MAPI handles array
1203
\param size pointer to the mapi_response size to update
1205
\return MAPI_E_SUCCESS on success, otherwise MAPI error
1207
_PUBLIC_ enum MAPISTATUS EcDoRpc_RopGetNamesFromIDs(TALLOC_CTX *mem_ctx,
1208
struct emsmdbp_context *emsmdbp_ctx,
1209
struct EcDoRpc_MAPI_REQ *mapi_req,
1210
struct EcDoRpc_MAPI_REPL *mapi_repl,
1211
uint32_t *handles, uint16_t *size)
1214
struct GetNamesFromIDs_req *request;
1215
struct GetNamesFromIDs_repl *response;
1216
struct MAPINAMEID *nameid;
1218
DEBUG(4, ("exchange_emsmdb: [OXCPRPT] GetNamesFromIDs (0x55)\n"));
1221
OPENCHANGE_RETVAL_IF(!emsmdbp_ctx, MAPI_E_NOT_INITIALIZED, NULL);
1222
OPENCHANGE_RETVAL_IF(!mapi_req, MAPI_E_INVALID_PARAMETER, NULL);
1223
OPENCHANGE_RETVAL_IF(!mapi_repl, MAPI_E_INVALID_PARAMETER, NULL);
1224
OPENCHANGE_RETVAL_IF(!handles, MAPI_E_INVALID_PARAMETER, NULL);
1225
OPENCHANGE_RETVAL_IF(!size, MAPI_E_INVALID_PARAMETER, NULL);
1227
mapi_repl->opnum = mapi_req->opnum;
1228
mapi_repl->error_code = MAPI_E_SUCCESS;
1229
mapi_repl->handle_idx = mapi_req->handle_idx;
1231
request = &mapi_req->u.mapi_GetNamesFromIDs;
1232
response = &mapi_repl->u.mapi_GetNamesFromIDs;
1234
response->nameid = talloc_array(mem_ctx, struct MAPINAMEID, request->PropertyIdCount);
1235
response->count = request->PropertyIdCount;
1236
for (i = 0; i < request->PropertyIdCount; i++) {
1237
if (request->PropertyIds[i] < 0x8000) {
1238
response->nameid[i].ulKind = MNID_ID;
1239
GUID_from_string(PS_MAPI, &response->nameid[i].lpguid);
1240
response->nameid[i].kind.lid = (uint32_t) request->PropertyIds[i] << 16 | get_property_type(request->PropertyIds[i]);
1242
else if (mapistore_namedprops_get_nameid(emsmdbp_ctx->mstore_ctx->nprops_ctx, request->PropertyIds[i], &nameid) == MAPISTORE_SUCCESS) {
1243
response->nameid[i] = *nameid;
1246
response->nameid[i].ulKind = 0xff;
1250
*size += libmapiserver_RopGetNamesFromIDs_size(mapi_repl);
1252
return MAPI_E_SUCCESS;
1256
\details EcDoRpc DeletePropertiesNoReplicate (0x7a) Rop. deletes property
1257
values from an object without invoking replication.
1259
\param mem_ctx pointer to the memory context
1260
\param emsmdbp_ctx pointer to the emsmdb provider context
1261
\param mapi_req pointer to the DeletePropertiesNoReplicate
1262
EcDoRpc_MAPI_REQ structure
1263
\param mapi_repl pointer to the DeletePropertiesNoReplicate
1264
EcDoRpc_MAPI_REPL structure
1265
\param handles pointer to the MAPI handles array
1266
\param size pointer to the mapi_response size to update
1268
\return MAPI_E_SUCCESS on success, otherwise MAPI error
1270
_PUBLIC_ enum MAPISTATUS EcDoRpc_RopDeletePropertiesNoReplicate(TALLOC_CTX *mem_ctx,
1271
struct emsmdbp_context *emsmdbp_ctx,
1272
struct EcDoRpc_MAPI_REQ *mapi_req,
1273
struct EcDoRpc_MAPI_REPL *mapi_repl,
1274
uint32_t *handles, uint16_t *size)
1276
DEBUG(4, ("exchange_emsmdb: [OXCPRPT] DeletePropertiesNoReplicate (0x7a) -- stub\n"));
1279
OPENCHANGE_RETVAL_IF(!emsmdbp_ctx, MAPI_E_NOT_INITIALIZED, NULL);
1280
OPENCHANGE_RETVAL_IF(!mapi_req, MAPI_E_INVALID_PARAMETER, NULL);
1281
OPENCHANGE_RETVAL_IF(!mapi_repl, MAPI_E_INVALID_PARAMETER, NULL);
1282
OPENCHANGE_RETVAL_IF(!handles, MAPI_E_INVALID_PARAMETER, NULL);
1283
OPENCHANGE_RETVAL_IF(!size, MAPI_E_INVALID_PARAMETER, NULL);
1285
mapi_repl->opnum = mapi_req->opnum;
1286
mapi_repl->error_code = MAPI_E_SUCCESS;
1287
mapi_repl->handle_idx = mapi_req->handle_idx;
1289
mapi_repl->u.mapi_DeletePropertiesNoReplicate.PropertyProblemCount = 0;
1290
mapi_repl->u.mapi_DeletePropertiesNoReplicate.PropertyProblem = NULL;
1292
*size += libmapiserver_RopDeletePropertiesNoReplicate_size(mapi_repl);
1294
return MAPI_E_SUCCESS;
1298
\details EcDoRpc CopyTo (0x39) Rop. This operation
1299
copy messages from one folder to another.
1301
\param mem_ctx pointer to the memory context
1302
\param emsmdbp_ctx pointer to the emsmdb provider context
1303
\param mapi_req pointer to the DeleteProperties EcDoRpc_MAPI_REQ
1305
\param mapi_repl pointer to the DeleteProperties EcDoRpc_MAPI_REPL
1307
\param handles pointer to the MAPI handles array
1308
\param size pointer to the mapi_response size to update
1310
\return MAPI_E_SUCCESS on success, otherwise MAPI error
1312
_PUBLIC_ enum MAPISTATUS EcDoRpc_RopCopyTo(TALLOC_CTX *mem_ctx,
1313
struct emsmdbp_context *emsmdbp_ctx,
1314
struct EcDoRpc_MAPI_REQ *mapi_req,
1315
struct EcDoRpc_MAPI_REPL *mapi_repl,
1316
uint32_t *handles, uint16_t *size)
1318
struct CopyTo_req *request;
1319
struct CopyTo_repl *response;
1320
enum MAPISTATUS retval;
1322
struct mapi_handles *rec = NULL;
1323
void *private_data = NULL;
1324
struct emsmdbp_object *source_object;
1325
struct emsmdbp_object *dest_object;
1326
struct SPropTagArray excluded_tags;
1328
DEBUG(4, ("exchange_emsmdb: [OXCPRPT] CopyTo (0x39)\n"));
1331
OPENCHANGE_RETVAL_IF(!emsmdbp_ctx, MAPI_E_NOT_INITIALIZED, NULL);
1332
OPENCHANGE_RETVAL_IF(!mapi_req, MAPI_E_INVALID_PARAMETER, NULL);
1333
OPENCHANGE_RETVAL_IF(!mapi_repl, MAPI_E_INVALID_PARAMETER, NULL);
1334
OPENCHANGE_RETVAL_IF(!handles, MAPI_E_INVALID_PARAMETER, NULL);
1335
OPENCHANGE_RETVAL_IF(!size, MAPI_E_INVALID_PARAMETER, NULL);
1337
request = &mapi_req->u.mapi_CopyTo;
1338
response = &mapi_repl->u.mapi_CopyTo;
1340
mapi_repl->opnum = mapi_req->opnum;
1341
mapi_repl->error_code = MAPI_E_SUCCESS;
1342
mapi_repl->handle_idx = mapi_req->handle_idx;
1344
response->PropertyProblemCount = 0;
1345
response->PropertyProblem = NULL;
1347
if (request->WantAsynchronous) {
1348
DEBUG(0, (" warning: asynchronous operations are not supported\n"));
1350
if ((request->CopyFlags & CopyFlagsMove)) {
1351
DEBUG(0, (" moving properties is not supported\n"));
1353
if ((request->CopyFlags & CopyFlagsNoOverwrite)) {
1354
DEBUG(0, (" properties WILL BE overwriten despite the operation flags\n"));
1357
/* Get the source object */
1358
handle = handles[mapi_req->handle_idx];
1359
retval = mapi_handles_search(emsmdbp_ctx->handles_ctx, handle, &rec);
1361
mapi_repl->error_code = MAPI_E_INVALID_OBJECT;
1362
DEBUG(0, (" handle (%x) not found: %x\n", handle, mapi_req->handle_idx));
1366
retval = mapi_handles_get_private_data(rec, &private_data);
1367
source_object = private_data;
1368
if (!source_object) {
1369
mapi_repl->error_code = MAPI_E_INVALID_OBJECT;
1370
DEBUG(0, (" object (%x) not found: %x\n", handle, mapi_req->handle_idx));
1374
/* Get the destination object */
1375
handle = handles[request->handle_idx];
1376
retval = mapi_handles_search(emsmdbp_ctx->handles_ctx, handle, &rec);
1378
mapi_repl->error_code = MAPI_E_INVALID_OBJECT;
1379
DEBUG(0, (" handle (%x) not found: %x\n", handle, mapi_req->handle_idx));
1383
retval = mapi_handles_get_private_data(rec, &private_data);
1384
dest_object = private_data;
1386
mapi_repl->error_code = MAPI_E_INVALID_OBJECT;
1387
DEBUG(0, (" object (%x) not found: %x\n", handle, mapi_req->handle_idx));
1391
excluded_tags.cValues = request->ExcludedTags.cValues;
1392
excluded_tags.aulPropTag = request->ExcludedTags.aulPropTag;
1394
mapi_repl->error_code = emsmdbp_object_copy_properties(emsmdbp_ctx, source_object, dest_object, &excluded_tags, request->WantSubObjects);
1397
*size += libmapiserver_RopCopyTo_size(mapi_repl);
1399
return MAPI_E_SUCCESS;