datarootdir=@datarootdir@
datadir=@datadir@
includedir=@includedir@
-mandir=@mandir@
+mandir=${prefix}/man
top_builddir=${PWD}
torture/openchange.$(SHLIBEXT): torture/testjoin_exchange.o \
torture/nspi_profile.o \
torture/nspi_resolvenames.o \
+ torture/mapi_copymail.o \
torture/mapi_prop.o \
torture/mapi_folder.o \
torture/mapi_table.o \
torture/mapi_sendattach.c \
torture/mapi_folder.c \
torture/mapi_table.c \
+ torture/mapi_copymail.c \
torture/mapi_prop.c \
torture/mapi_message.c \
torture/mapi_fetchattach.c \
op_MAPI_ReadStream = 0x2c,
op_MAPI_WriteStream = 0x2d,
op_MAPI_SubmitMessage = 0x32,
+ op_MAPI_CopyMessages = 0x33,
op_MAPI_QueryColumns = 0x37,
op_MAPI_EmptyFolder = 0x58,
op_MAPI_GetReceiveFolderTable = 0x68,
// uint8 unknown[3];
} SubmitMessage_repl;
+ /*************************/
+ /* EcDoRpc Function 0x33 */
+ typedef [flag(NDR_NOALIGN)] struct {
+ uint8 handle_idx;
+ uint16 count;
+ hyper message_id[count];
+ uint16 row_nb;
+ } CopyMessages_req;
+
+ typedef [flag(NDR_NOALIGN)] struct {
+ uint8 unknown;
+ } CopyMessages_repl;
/*************************/
/* EcDoRpc Function 0x37 */
[case(op_MAPI_ReadStream)] ReadStream_req mapi_ReadStream;
[case(op_MAPI_WriteStream)] WriteStream_req mapi_WriteStream;
[case(op_MAPI_SubmitMessage)] SubmitMessage_req mapi_SubmitMessage;
+ [case(op_MAPI_CopyMessages)] CopyMessages_req mapi_CopyMessages;
[case(op_MAPI_QueryColumns)] QueryColumns_req mapi_QueryColumns;
[case(op_MAPI_EmptyFolder)] EmptyFolder_req mapi_EmptyFolder;
[case(op_MAPI_OpenMsgStore)] OpenMsgStore_req mapi_OpenMsgStore;
[case(op_MAPI_ReadStream)] ReadStream_repl mapi_ReadStream;
[case(op_MAPI_WriteStream)] WriteStream_repl mapi_WriteStream;
[case(op_MAPI_SubmitMessage)] SubmitMessage_repl mapi_SubmitMessage;
+ [case(op_MAPI_CopyMessages)] CopyMessages_repl mapi_CopyMessages;
[case(op_MAPI_QueryColumns)] QueryColumns_repl mapi_QueryColumns;
[case(op_MAPI_EmptyFolder)] EmptyFolder_repl mapi_EmptyFolder;
[case(op_MAPI_OpenMsgStore)] OpenMsgStore_repl mapi_OpenMsgStore;
libdir=@libdir@
includedir=@includedir@
datadir=@datadir@
+datarootdir=@prefix@/share
Name: MAPI
Description: MAPI Protocol Implementation
return MAPI_E_SUCCESS;
}
+/**
+ * Copy or move a message from a folder to another
+ *
+ */
+_PUBLIC_ enum MAPISTATUS CopyMessages(mapi_object_t *obj_src,
+ mapi_object_t *obj_dst,
+ mapi_id_t msgid)
+{
+ NTSTATUS status;
+ TALLOC_CTX *mem_ctx;
+ enum MAPISTATUS retval;
+ struct mapi_request *mapi_request;
+ struct mapi_response *mapi_response;
+ struct EcDoRpc_MAPI_REQ *mapi_req;
+ struct CopyMessages_req request;
+ uint32_t size;
+
+ MAPI_RETVAL_IF(!global_mapi_ctx, MAPI_E_NOT_INITIALIZED, NULL);
+
+ mem_ctx = talloc_init("CopyMessages");
+
+ size = 0;
+
+ /* FIXME: the function can take an array of msgids and is not
+ * limited to a unique msgid
+ */
+
+ /* Fill the CopyMessage operation */
+ request.handle_idx = 0x1;
+ size += sizeof (uint8_t);
+ request.count = 0x1;
+ size += sizeof (uint16_t);
+ request.message_id = talloc_array(mem_ctx, uint64_t, 1);
+ request.message_id[0] = msgid;
+ size += sizeof (mapi_id_t);
+ request.row_nb = 0x0;
+ size += sizeof (uint16_t);
+
+ /* Fill the MAPI_REQ request */
+ mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ);
+ mapi_req->opnum = op_MAPI_CopyMessages;
+ mapi_req->mapi_flags = 0;
+ mapi_req->handle_idx = 0;
+ mapi_req->u.mapi_CopyMessages = request;
+ size += 5;
+
+ /* Fill the mapi_request structure */
+ mapi_request = talloc_zero(mem_ctx, struct mapi_request);
+ mapi_request->mapi_len = size + sizeof (uint32_t) * 2;
+ mapi_request->length = size;
+ mapi_request->mapi_req = mapi_req;
+ mapi_request->handles = talloc_array(mem_ctx, uint32_t, 2);
+ mapi_request->handles[0] = mapi_object_get_handle(obj_src);
+ mapi_request->handles[1] = mapi_object_get_handle(obj_dst);
+
+ status = emsmdb_transaction(global_mapi_ctx->session->emsmdb->ctx, mapi_request, &mapi_response);
+ MAPI_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx);
+ retval = mapi_response->mapi_repl->error_code;
+ MAPI_RETVAL_IF(retval, retval, mem_ctx);
+
+ talloc_free(mapi_response);
+ talloc_free(mem_ctx);
+
+ return MAPI_E_SUCCESS;
+}
+
+
/**
* SetReadFlags: method sets or clears the MSGFLAG_READ flag in the
* PR_MESSAGE_FLAGS property
--- /dev/null
+/*
+ OpenChange MAPI implementation testsuite
+
+ Copy message from a folder to another
+
+ Copyright (C) Julien Kerihuel 2007
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include <libmapi/libmapi.h>
+#include <gen_ndr/ndr_exchange.h>
+#include <param.h>
+#include <credentials.h>
+#include <torture/torture.h>
+#include <torture/torture_proto.h>
+#include <torture/mapi_torture.h>
+#include <samba/popt.h>
+
+BOOL torture_rpc_mapi_copymail(struct torture_context *torture)
+{
+ NTSTATUS status;
+ enum MAPISTATUS retval;
+ struct dcerpc_pipe *p;
+ TALLOC_CTX *mem_ctx;
+ struct mapi_session *session;
+ mapi_object_t obj_store;
+ mapi_object_t obj_dir_src;
+ mapi_object_t obj_dir_dst;
+ mapi_object_t obj_table;
+ mapi_id_t id_src;
+ mapi_id_t id_dst;
+ struct SPropTagArray *SPropTagArray = NULL;
+ struct SRowSet rowset;
+ int i;
+
+ /* init torture */
+ mem_ctx = talloc_init("torture_rpc_mapi_copymail");
+ status = torture_rpc_connection(mem_ctx, &p, &dcerpc_table_exchange_emsmdb);
+ if (!NT_STATUS_IS_OK(status)) {
+ talloc_free(mem_ctx);
+ return False;
+ }
+
+ /* init mapi */
+ if ((session = torture_init_mapi(mem_ctx)) == NULL) return False;
+
+ /* init objects */
+ mapi_object_init(&obj_store);
+ mapi_object_init(&obj_dir_src);
+ mapi_object_init(&obj_dir_dst);
+ mapi_object_init(&obj_table);
+
+ /* OpenMsgStore */
+ retval = OpenMsgStore(&obj_store);
+ mapi_errstr("OpenMsgStore", GetLastError());
+ if (retval != MAPI_E_SUCCESS) return False;
+
+ /* Get Inbox folder */
+ retval = GetDefaultFolder(&obj_store, &id_src, olFolderInbox);
+ mapi_errstr("GetDefaultFolder", GetLastError());
+ if (retval != MAPI_E_SUCCESS) return False;
+
+ retval = OpenFolder(&obj_store, id_src, &obj_dir_src);
+ mapi_errstr("OpenFolder", GetLastError());
+ if (retval != MAPI_E_SUCCESS) return False;
+
+ /* Get Deleted Items folder */
+ retval = GetDefaultFolder(&obj_store, &id_dst, olFolderDrafts);
+ mapi_errstr("GetDefaultFolder", GetLastError());
+ if (retval != MAPI_E_SUCCESS) return False;
+
+ retval = OpenFolder(&obj_store, id_dst, &obj_dir_dst);
+ mapi_errstr("OpenFolder", GetLastError());
+ if (retval != MAPI_E_SUCCESS) return False;
+
+
+ retval = GetContentsTable(&obj_dir_src, &obj_table);
+ mapi_errstr("GetContentsTable", GetLastError());
+ if (retval != MAPI_E_SUCCESS) return False;
+
+ SPropTagArray = set_SPropTagArray(mem_ctx, 0x5,
+ PR_FID,
+ PR_MID,
+ PR_INST_ID,
+ PR_INSTANCE_NUM,
+ PR_SUBJECT);
+ retval = SetColumns(&obj_table, SPropTagArray);
+ MAPIFreeBuffer(SPropTagArray);
+ mapi_errstr("SetColumns", GetLastError());
+ if (retval != MAPI_E_SUCCESS) return False;
+
+ while ((retval = QueryRows(&obj_table, 0xa, TBL_ADVANCE, &rowset)) != MAPI_E_NOT_FOUND && rowset.cRows) {
+ for (i = 0; i < rowset.cRows; i++) {
+ retval = CopyMessages(&obj_dir_src, &obj_dir_dst, rowset.aRow[i].lpProps[1].value.d);
+ mapi_errstr("CopyMessages", GetLastError());
+ if (retval != MAPI_E_SUCCESS) return False;
+ }
+ }
+
+ /* release mapi objects
+ */
+ mapi_object_release(&obj_table);
+ mapi_object_release(&obj_dir_src);
+ mapi_object_release(&obj_dir_dst);
+ mapi_object_release(&obj_store);
+
+ /* uninitialize mapi
+ */
+ MAPIUninitialize();
+ talloc_free(mem_ctx);
+
+ return True;
+}
torture_suite_add_simple_test(suite, "MAPI-SENDATTACH", torture_rpc_mapi_sendattach);
torture_suite_add_simple_test(suite, "MAPI-DELETEMAIL", torture_rpc_mapi_deletemail);
torture_suite_add_simple_test(suite, "MAPI-NEWMAIL", torture_rpc_mapi_newmail);
+ torture_suite_add_simple_test(suite, "MAPI-COPYMAIL", torture_rpc_mapi_copymail);
/* MAPI calendar torture tests */
torture_suite_add_simple_test(suite, "MAPI-FETCHAPPOINTMENT", torture_rpc_mapi_fetchappointment);
torture_suite_add_simple_test(suite, "MAPI-SENDAPPOINTMENT", torture_rpc_mapi_sendappointment);