[Pkg-samba-maint] r2734 - in trunk/openchange: . debian libmapi libmapi/conf mapiproxy torture utils utils/mapitest utils/mapitest/modules
jelmer at alioth.debian.org
jelmer at alioth.debian.org
Thu Apr 30 18:06:50 UTC 2009
Author: jelmer
Date: 2009-04-30 18:06:50 +0000 (Thu, 30 Apr 2009)
New Revision: 2734
Modified:
trunk/openchange/.bzrignore
trunk/openchange/ChangeLog
trunk/openchange/debian/changelog
trunk/openchange/exchange.idl
trunk/openchange/libmapi/FXICS.c
trunk/openchange/libmapi/IMAPIContainer.c
trunk/openchange/libmapi/IMAPIFolder.c
trunk/openchange/libmapi/IMAPIProp.c
trunk/openchange/libmapi/IMAPISession.c
trunk/openchange/libmapi/IMAPISupport.c
trunk/openchange/libmapi/IMAPITable.c
trunk/openchange/libmapi/IMessage.c
trunk/openchange/libmapi/IMsgStore.c
trunk/openchange/libmapi/IStoreFolder.c
trunk/openchange/libmapi/IStream.c
trunk/openchange/libmapi/IUnknown.c
trunk/openchange/libmapi/IXPLogon.c
trunk/openchange/libmapi/conf/mapi-properties
trunk/openchange/libmapi/conf/mparse.pl
trunk/openchange/libmapi/mapi_notification.h
trunk/openchange/libmapi/x500.c
trunk/openchange/mapiproxy/dcesrv_mapiproxy.c
trunk/openchange/torture/mapi_newmail.c
trunk/openchange/utils/mapitest/mapitest_common.c
trunk/openchange/utils/mapitest/module.c
trunk/openchange/utils/mapitest/modules/module_oxcfold.c
trunk/openchange/utils/mapitest/modules/module_oxcnotif.c
trunk/openchange/utils/mapitest/modules/module_oxcprpt.c
trunk/openchange/utils/mapitest/modules/module_oxomsg.c
trunk/openchange/utils/openchangeclient.c
Log:
Merge new upstream snapshot.
Modified: trunk/openchange/.bzrignore
===================================================================
--- trunk/openchange/.bzrignore 2009-04-30 18:06:45 UTC (rev 2733)
+++ trunk/openchange/.bzrignore 2009-04-30 18:06:50 UTC (rev 2734)
@@ -64,3 +64,4 @@
libmapi++/examples/messages
bin/mapistore_test
_trial_temp
+mapiproxy/libmapiproxy/openchangedb_property.c
Modified: trunk/openchange/ChangeLog
===================================================================
--- trunk/openchange/ChangeLog 2009-04-30 18:06:45 UTC (rev 2733)
+++ trunk/openchange/ChangeLog 2009-04-30 18:06:50 UTC (rev 2734)
@@ -1,3 +1,121 @@
+2009-04-27
+ jkerihuel
+ [r1339]
+ Patch from Paolo Abeni <paolo.abeni at gmail.com>:
+
+ call ProcessNotification() after each successful
+ emsmdb_transaction() in all the libmapi calls.
+ [r1338]
+ Patch from Paolo Abeni <paolo.abeni at gmail.com>:
+
+ Mapi notifications can occurs inside any emsmdb_transaction; currently
+ only the notification send by the server inside the
+ emsmdb_transaction_null() in MonitorNotification() are
+ parsed/processed/delivered to the appropriate callback.
+
+ To be able to process all the received notifications, the notification
+ structure must comprise the private data to be passed to the
+ notification callback, since in the average mapi call this data is not
+ available. This patch modifies the Subscribe() call and the
+ mapi_notification structure, adding the private_data parameter (also the
+ related Subscribe() calls are update) and add a libmapi call
+ (DispatchNotifications) to force the notification dispatching in
+ a [quite] non blocking way
+
+2009-04-26
+ jkerihuel
+ [r1336]
+ Patch from Paolo Abeni <paolo.abeni at gmail.com>:
+
+ ProcessNotification() is ignoring the handle value contained into the
+ processed notifications. This means that if many Subscribe() calls are
+ performed on different folders but with the same flags, all the
+ registered callback are [incorrectly] signaled with each received
+ notification.
+
+ The attached patch match the handler contained into the notification
+ message against the notification object handle to avoid such
+ replication.
+
+2009-04-23
+ jkerihuel
+ [r1331]
+ Make sure delayed authenication is not called when server mode is enabled
+ bradh
+ [r1333]
+ Update property list to reflect current OAB props.
+
+ This deletes a few incompatible properties. Cannot determine the history of the PR_MAILBEAT_ props.
+ [r1332]
+ Fix display of Folder ID values (one is filled with ., the other is prefixed with .16 instead of being filled.
+
+ Also remove duplicate close() of file descriptor.
+ [r1330]
+ Typo fix.
+
+2009-04-22
+ bradh
+ [r1328]
+ Warning fix.
+
+2009-04-21
+ bradh
+ [r1326]
+ Implement RopTransportNewMail (0x51).
+
+ Includes IDL, libmapi implementation, and basic mapitest coverage.
+
+ Also fix a few doxygen / formatting things.
+
+2009-04-19
+ jkerihuel
+ [r1324]
+ - Add Redirect buffer support for OpenMsgStore and OpenPublicFolder.
+ This commit fixes the ecWrongServer (0x478) error users encounter
+ while running openchange based software in a clustered Exchange
+ environment.
+
+2009-04-18
+ bradh
+ [r1322]
+ Implement RopCloneStream (0x3b) and RopWriteAndCommitStream (0x90).
+
+ Includes IDL, implementation and mapitest tests.
+
+2009-04-17
+ bradh
+ [r1320]
+ Fix Search notifications.
+
+ MS concurred that the docs are wrong.
+
+ Patch by Paolo Abeni - thanks very much for the
+ investigation and the patch.
+ [r1319]
+ Update GetStoreState documentation.
+ [r1318]
+ Implement RopSetPropertiesNoReplicate (0x79).
+
+ IDL was already done. mapitest for DeletePropertiesNoReplicate was
+ reused / updated.
+
+2009-04-16
+ bradh
+ [r1316]
+ Implement (IDL, libmapi, mapitest) RopHardDeleteMessagesAndSubfolders (0x92)
+
+ Also fix some bugs in mapitest common code, and an incorrect sanity check in CreateFolder().
+
+2009-04-15
+ bradh
+ [r1314]
+ Implement RopHardDeleteMessages (0x91).
+
+ Includes IDL, implementation and mapitest.
+ jelmer
+ [r1313]
+ Ignore generated property file.
+
2009-04-13
bradh
[r1311]
Modified: trunk/openchange/debian/changelog
===================================================================
--- trunk/openchange/debian/changelog 2009-04-30 18:06:45 UTC (rev 2733)
+++ trunk/openchange/debian/changelog 2009-04-30 18:06:50 UTC (rev 2734)
@@ -1,4 +1,4 @@
-openchange (1:0.8.2+svn1312-1) experimental; urgency=low
+openchange (1:0.8.2+svn1340-1) experimental; urgency=low
* New upstream snapshot.
* Build exchange2ical.
Modified: trunk/openchange/exchange.idl
===================================================================
--- trunk/openchange/exchange.idl 2009-04-30 18:06:45 UTC (rev 2733)
+++ trunk/openchange/exchange.idl 2009-04-30 18:06:50 UTC (rev 2734)
@@ -837,6 +837,7 @@
op_MAPI_Abort = 0x38,
op_MAPI_CopyTo = 0x39,
op_MAPI_CopyToStream = 0x3a,
+ op_MAPI_CloneStream = 0x3b,
op_MAPI_GetTable = 0x3e,
op_MAPI_GetRulesTable = 0x3f,
op_MAPI_ModifyTable = 0x40,
@@ -853,6 +854,7 @@
op_MAPI_FastTransferSourceGetBuffer = 0x4e,
op_MAPI_FindRow = 0x4f,
op_MAPI_Progress = 0x50,
+ op_MAPI_TransportNewMail = 0x51,
op_MAPI_GetNamesFromIDs = 0x55,
op_MAPI_GetIDsFromNames = 0x56,
op_MAPI_UpdateDeferredActionMessages = 0x57,
@@ -894,6 +896,9 @@
op_MAPI_OpenPublicFolderByName = 0x87,
op_MAPI_SetSyncNotificationGuid = 0x88,
op_MAPI_FreeBookmark = 0x89,
+ op_MAPI_WriteAndCommitStream = 0x90,
+ op_MAPI_HardDeleteMessages = 0x91,
+ op_MAPI_HardDeleteMessagesAndSubfolders = 0x92,
op_MAPI_Logon = 0xfe,
/****** custom MAPI opnum for mapiproxy ******/
op_MAPI_proxypack = 0xa5
@@ -2219,6 +2224,15 @@
[switch_is(TableEvent)] ContentsTableChangeUnion ContentsTableChangeUnion;
} ContentsTableChange;
+ /* SearchMessageCreatedNotification: case 0xc004 */
+ typedef [flag(NDR_NOALIGN)] struct {
+ hyper FID;
+ hyper MID;
+ hyper SearchFID;
+ uint16 TagCount;
+ MAPITAGS Tags[TagCount];
+ } SearchMessageCreatedNotification;
+
/* SearchMessageRemovedNotification: case 0xc008 */
typedef [flag(NDR_NOALIGN)] struct {
hyper FID;
@@ -2230,7 +2244,6 @@
typedef [flag(NDR_NOALIGN)] struct {
hyper FID;
hyper MID;
- hyper SearchFID;
uint16 TagCount;
MAPITAGS Tags[TagCount];
} SearchMessageModifiedNotification;
@@ -2255,6 +2268,7 @@
[case(0x8020)] MessageMoveCopyNotification MessageMoveNotification;
[case(0x8040)] MessageMoveCopyNotification MessageCopyNotification;
[case(0x8100)] ContentsTableChange ContentsTableChange;
+ [case(0xc004)] SearchMessageCreatedNotification SearchMessageCreatedNotification;
[case(0xc008)] SearchMessageRemovedNotification SearchMessageRemovedNotification;
[case(0xc010)] SearchMessageModifiedNotification SearchMessageModifiedNotification;
[case(0xc100)] ContentsTableChange SearchTableChange;
@@ -2498,6 +2512,15 @@
} CopyToStream_repl;
/*************************/
+ /* EcDoRpc Function 0x3b */
+ typedef [flag(NDR_NOALIGN)] struct {
+ uint8 handle_idx;
+ } CloneStream_req;
+
+ typedef [flag(NDR_NOALIGN)] struct {
+ } CloneStream_repl;
+
+ /*************************/
/* EcDoRpc Function 0x3e */
typedef [flag(NDR_NOALIGN)] struct {
uint8 handle_idx;
@@ -2730,6 +2753,18 @@
uint32 TotalTaskCount;
} Progress_repl;
+ /**************************/
+ /* EcDoRpc Function 0x51 */
+ typedef [flag(NDR_NOALIGN)] struct {
+ hyper MessageId;
+ hyper FolderId;
+ astring MessageClass;
+ uint32 MessageFlags;
+ } TransportNewMail_req;
+
+ typedef [flag(NDR_NOALIGN)] struct {
+ } TransportNewMail_repl;
+
/*************************/
/* EcDoRpc Function 0x55 */
typedef [enum8bit] enum {
@@ -3280,6 +3315,41 @@
} FreeBookmark_repl;
/*************************/
+ /* EcDoRpc Function 0x90 */
+ typedef [flag(NDR_NOALIGN)] struct {
+ [subcontext(2), flag(NDR_REMAINING)] DATA_BLOB data;
+ } WriteAndCommitStream_req;
+
+
+ typedef [flag(NDR_NOALIGN)] struct {
+ uint16 WrittenSize;
+ } WriteAndCommitStream_repl;
+
+ /**************************/
+ /* EcDoRpc Function 0x91 */
+ typedef [flag(NDR_NOALIGN)] struct {
+ boolean8 WantAsynchronous;
+ boolean8 NotifyNonRead;
+ uint16 MessageIdCount;
+ hyper MessageIds[MessageIdCount];
+ } HardDeleteMessages_req;
+
+ typedef [flag(NDR_NOALIGN)] struct {
+ boolean8 PartialCompletion;
+ } HardDeleteMessages_repl;
+
+ /*************************/
+ /* EcDoRpc Function 0x92 */
+ typedef [flag(NDR_NOALIGN)] struct {
+ boolean8 WantAsynchronous;
+ boolean8 WantDeleteAssociated;
+ } HardDeleteMessagesAndSubfolders_req;
+
+ typedef [flag(NDR_NOALIGN)] struct {
+ boolean8 PartialCompletion;
+ } HardDeleteMessagesAndSubfolders_repl;
+
+ /*************************/
/* EcDoRpc Function 0xFE */
typedef [public,bitmap8bit] bitmap {
LogonPrivate = 0x1,
@@ -3434,6 +3504,7 @@
[case(op_MAPI_Abort)] Abort_req mapi_Abort;
[case(op_MAPI_CopyTo)] CopyTo_req mapi_CopyTo;
[case(op_MAPI_CopyToStream)] CopyToStream_req mapi_CopyToStream;
+ [case(op_MAPI_CloneStream)] CloneStream_req mapi_CloneStream;
[case(op_MAPI_GetTable)] GetTable_req mapi_GetTable;
[case(op_MAPI_GetRulesTable)] GetRulesTable_req mapi_GetRulesTable;
[case(op_MAPI_ModifyTable)] ModifyTable_req mapi_ModifyTable;
@@ -3450,6 +3521,7 @@
[case(op_MAPI_FastTransferSourceGetBuffer)] FastTransferSourceGetBuffer_req mapi_FastTransferSourceGetBuffer;
[case(op_MAPI_FindRow)] FindRow_req mapi_FindRow;
[case(op_MAPI_Progress)] Progress_req mapi_Progress;
+ [case(op_MAPI_TransportNewMail)] TransportNewMail_req mapi_TransportNewMail;
[case(op_MAPI_GetNamesFromIDs)] GetNamesFromIDs_req mapi_GetNamesFromIDs;
[case(op_MAPI_GetIDsFromNames)] GetIDsFromNames_req mapi_GetIDsFromNames;
[case(op_MAPI_UpdateDeferredActionMessages)] UpdateDeferredActionMessages_req mapi_UpdateDeferredActionMessages;
@@ -3490,6 +3562,9 @@
[case(op_MAPI_OpenPublicFolderByName)] OpenPublicFolderByName_req mapi_OpenPublicFolderByName;
[case(op_MAPI_SetSyncNotificationGuid)] SetSyncNotificationGuid_req mapi_SetSyncNotificationGuid;
[case(op_MAPI_FreeBookmark)] FreeBookmark_req mapi_FreeBookmark;
+ [case(op_MAPI_WriteAndCommitStream)] WriteAndCommitStream_req mapi_WriteAndCommitStream;
+ [case(op_MAPI_HardDeleteMessages)] HardDeleteMessages_req mapi_HardDeleteMessages;
+ [case(op_MAPI_HardDeleteMessagesAndSubfolders)] HardDeleteMessagesAndSubfolders_req mapi_HardDeleteMessagesAndSubfolders;
[case(op_MAPI_Logon)] Logon_req mapi_Logon;
[case(op_MAPI_proxypack)] proxypack_req mapi_proxypack;
} EcDoRpc_MAPI_REQ_UNION;
@@ -3551,6 +3626,7 @@
[case(op_MAPI_Abort)] Abort_repl mapi_Abort;
[case(op_MAPI_CopyTo)] CopyTo_repl mapi_CopyTo;
[case(op_MAPI_CopyToStream)] CopyToStream_repl mapi_CopyToStream;
+ [case(op_MAPI_CloneStream)] CloneStream_repl mapi_CloneStream;
[case(op_MAPI_GetTable)] GetTable_repl mapi_GetTable;
[case(op_MAPI_GetRulesTable)] GetRulesTable_repl mapi_GetRulesTable;
[case(op_MAPI_ModifyTable)] ModifyTable_repl mapi_ModifyTable;
@@ -3567,6 +3643,7 @@
[case(op_MAPI_FastTransferSourceGetBuffer)] FastTransferSourceGetBuffer_repl mapi_FastTransferSourceGetBuffer;
[case(op_MAPI_FindRow)] FindRow_repl mapi_FindRow;
[case(op_MAPI_Progress)] Progress_repl mapi_Progress;
+ [case(op_MAPI_TransportNewMail)] TransportNewMail_repl mapi_TransportNewMail;
[case(op_MAPI_GetNamesFromIDs)] GetNamesFromIDs_repl mapi_GetNamesFromIDs;
[case(op_MAPI_GetIDsFromNames)] GetIDsFromNames_repl mapi_GetIDsFromNames;
[case(op_MAPI_UpdateDeferredActionMessages)] UpdateDeferredActionMessages_repl mapi_UpdateDeferredActionMessages;
@@ -3608,6 +3685,9 @@
[case(op_MAPI_OpenPublicFolderByName)] OpenPublicFolderByName_repl mapi_OpenPublicFolderByName;
[case(op_MAPI_SetSyncNotificationGuid)] SetSyncNotificationGuid_repl mapi_SetSyncNotificationGuid;
[case(op_MAPI_FreeBookmark)] FreeBookmark_repl mapi_FreeBookmark;
+ [case(op_MAPI_WriteAndCommitStream)] WriteAndCommitStream_repl mapi_WriteAndCommitStream;
+ [case(op_MAPI_HardDeleteMessages)] HardDeleteMessages_repl mapi_HardDeleteMessages;
+ [case(op_MAPI_HardDeleteMessagesAndSubfolders)] HardDeleteMessagesAndSubfolders_repl mapi_HardDeleteMessagesAndSubfolders;
[case(op_MAPI_Logon)] Logon_repl mapi_Logon;
[case(op_MAPI_proxypack)] proxypack_repl mapi_proxypack;
Modified: trunk/openchange/libmapi/FXICS.c
===================================================================
--- trunk/openchange/libmapi/FXICS.c 2009-04-30 18:06:45 UTC (rev 2733)
+++ trunk/openchange/libmapi/FXICS.c 2009-04-30 18:06:50 UTC (rev 2734)
@@ -101,6 +101,8 @@
OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx);
retval = mapi_response->mapi_repl->error_code;
OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
+
+ OPENCHANGE_CHECK_NOTIFICATION(session, mapi_response);
/* Retrieve output parameters */
reply = &mapi_response->mapi_repl->u.mapi_GetLocalReplicaIds;
Modified: trunk/openchange/libmapi/IMAPIContainer.c
===================================================================
--- trunk/openchange/libmapi/IMAPIContainer.c 2009-04-30 18:06:45 UTC (rev 2733)
+++ trunk/openchange/libmapi/IMAPIContainer.c 2009-04-30 18:06:50 UTC (rev 2734)
@@ -132,6 +132,8 @@
retval = mapi_response->mapi_repl->error_code;
OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
+ OPENCHANGE_CHECK_NOTIFICATION(session, mapi_response);
+
/* set object session, handle and logon_id */
mapi_object_set_session(obj_table, session);
mapi_object_set_handle(obj_table, mapi_response->handles[1]);
@@ -256,6 +258,8 @@
retval = mapi_response->mapi_repl->error_code;
OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
+ OPENCHANGE_CHECK_NOTIFICATION(session, mapi_response);
+
/* set object session, handle and logon_id */
mapi_object_set_session(obj_table, session);
mapi_object_set_handle(obj_table, mapi_response->handles[1]);
@@ -349,6 +353,8 @@
retval = mapi_response->mapi_repl->error_code;
OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
+ OPENCHANGE_CHECK_NOTIFICATION(session, mapi_response);
+
/* set object session, handle and logon_id */
mapi_object_set_session(obj_table, session);
mapi_object_set_handle(obj_table, mapi_response->handles[1]);
@@ -444,6 +450,8 @@
retval = mapi_response->mapi_repl->error_code;
OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
+ OPENCHANGE_CHECK_NOTIFICATION(session, mapi_response);
+
/* set object session, handle and logon_id */
mapi_object_set_session(obj_table, session);
mapi_object_set_handle(obj_table, mapi_response->handles[1]);
@@ -542,6 +550,8 @@
retval = mapi_response->mapi_repl->error_code;
OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
+ OPENCHANGE_CHECK_NOTIFICATION(session, mapi_response);
+
talloc_free(mapi_response);
talloc_free(mem_ctx);
@@ -660,6 +670,8 @@
retval = mapi_response->mapi_repl->error_code;
OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
+ OPENCHANGE_CHECK_NOTIFICATION(session, mapi_response);
+
talloc_free(mapi_response);
talloc_free(mem_ctx);
@@ -747,6 +759,8 @@
retval = mapi_response->mapi_repl->error_code;
OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
+ OPENCHANGE_CHECK_NOTIFICATION(session, mapi_response);
+
reply = &mapi_response->mapi_repl->u.mapi_GetSearchCriteria;
res = &reply->res;
Modified: trunk/openchange/libmapi/IMAPIFolder.c
===================================================================
--- trunk/openchange/libmapi/IMAPIFolder.c 2009-04-30 18:06:45 UTC (rev 2733)
+++ trunk/openchange/libmapi/IMAPIFolder.c 2009-04-30 18:06:50 UTC (rev 2734)
@@ -103,6 +103,8 @@
retval = mapi_response->mapi_repl->error_code;
OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
+ OPENCHANGE_CHECK_NOTIFICATION(session, mapi_response);
+
/* set object session and handle */
mapi_object_set_session(obj_message, session);
mapi_object_set_handle(obj_message, mapi_response->handles[1]);
@@ -189,6 +191,8 @@
retval = mapi_response->mapi_repl->error_code;
OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
+ OPENCHANGE_CHECK_NOTIFICATION(session, mapi_response);
+
talloc_free(mapi_response);
talloc_free(mem_ctx);
@@ -197,6 +201,89 @@
/**
+ \details Hard delete one or more messages
+
+ This function hard deletes one or more messages based on their
+ ids from a specified folder.
+
+ \param obj_folder the folder to hard delete messages from
+ \param id_messages the list of ids
+ \param cn_messages the number of messages in the id list.
+
+ \return MAPI_E_SUCCESS on success, otherwise MAPI error.
+
+ \note Developers may also call GetLastError() to retrieve the last
+ MAPI error code. Possible MAPI error codes are:
+ - MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized
+ - MAPI_E_INVALID_PARAMETER: the parent folder was not valid
+ - MAPI_E_CALL_FAILED: A network problem was encountered during the
+ transaction
+
+ \sa OpenFolder, CreateMessage, GetLastError
+*/
+_PUBLIC_ enum MAPISTATUS HardDeleteMessage(mapi_object_t *obj_folder,
+ mapi_id_t *id_messages,
+ uint16_t cn_messages)
+{
+ struct mapi_request *mapi_request;
+ struct mapi_response *mapi_response;
+ struct EcDoRpc_MAPI_REQ *mapi_req;
+ struct HardDeleteMessages_req request;
+ struct mapi_session *session;
+ NTSTATUS status;
+ enum MAPISTATUS retval;
+ uint32_t size;
+ TALLOC_CTX *mem_ctx;
+
+ /* Sanity checks */
+ OPENCHANGE_RETVAL_IF(!global_mapi_ctx, MAPI_E_NOT_INITIALIZED, NULL);
+ OPENCHANGE_RETVAL_IF(!obj_folder, MAPI_E_INVALID_PARAMETER, NULL);
+ session = mapi_object_get_session(obj_folder);
+ OPENCHANGE_RETVAL_IF(!session, MAPI_E_INVALID_PARAMETER, NULL);
+
+ mem_ctx = talloc_named(NULL, 0, "HardDeleteMessages");
+ size = 0;
+
+ /* Fill the HardDeleteMessages operation */
+ request.WantAsynchronous = 0x0;
+ size += sizeof (uint8_t);
+ request.NotifyNonRead = 0x1;
+ size += sizeof(uint8_t);
+ request.MessageIdCount = cn_messages;
+ size += sizeof(uint16_t);
+ request.MessageIds = id_messages;
+ size += request.MessageIdCount * sizeof(mapi_id_t);
+
+ /* Fill the MAPI_REQ request */
+ mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ);
+ mapi_req->opnum = op_MAPI_HardDeleteMessages;
+ mapi_req->logon_id = mapi_object_get_logon_id(obj_folder);
+ mapi_req->handle_idx = 0;
+ mapi_req->u.mapi_HardDeleteMessages = 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);
+ mapi_request->length = size;
+ mapi_request->mapi_req = mapi_req;
+ mapi_request->handles = talloc_array(mem_ctx, uint32_t, 1);
+ mapi_request->handles[0] = mapi_object_get_handle(obj_folder);
+
+ status = emsmdb_transaction(session->emsmdb->ctx, mapi_request, &mapi_response);
+ OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx);
+ OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx);
+ retval = mapi_response->mapi_repl->error_code;
+ OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
+
+ talloc_free(mapi_response);
+ talloc_free(mem_ctx);
+
+ return MAPI_E_SUCCESS;
+}
+
+
+/**
\details Obtain the status associated with a message
This function obtains the status associated with a message in the
@@ -264,6 +351,8 @@
retval = mapi_response->mapi_repl->error_code;
OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
+ OPENCHANGE_CHECK_NOTIFICATION(session, mapi_response);
+
*ulStatus = mapi_response->mapi_repl->u.mapi_SetMessageStatus.ulOldStatus;
talloc_free(mapi_response);
@@ -364,6 +453,8 @@
retval = mapi_response->mapi_repl->error_code;
OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
+ OPENCHANGE_CHECK_NOTIFICATION(session, mapi_response);
+
*ulOldStatus = mapi_response->mapi_repl->u.mapi_SetMessageStatus.ulOldStatus;
talloc_free(mapi_response);
@@ -463,6 +554,8 @@
OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx);
retval = mapi_response->mapi_repl->error_code;
OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
+
+ OPENCHANGE_CHECK_NOTIFICATION(session[0], mapi_response);
talloc_free(mapi_response);
talloc_free(mem_ctx);
@@ -525,7 +618,7 @@
OPENCHANGE_RETVAL_IF(!obj_parent, MAPI_E_INVALID_PARAMETER, NULL);
OPENCHANGE_RETVAL_IF(!name, MAPI_E_NOT_INITIALIZED, NULL);
session = mapi_object_get_session(obj_parent);
- OPENCHANGE_RETVAL_IF(!obj_parent, MAPI_E_INVALID_PARAMETER, NULL);
+ OPENCHANGE_RETVAL_IF(!session, MAPI_E_INVALID_PARAMETER, NULL);
logon_id = mapi_object_get_logon_id(obj_parent);
@@ -611,6 +704,8 @@
retval = mapi_response->mapi_repl->error_code;
OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
+ OPENCHANGE_CHECK_NOTIFICATION(session, mapi_response);
+
/* Set object session, handle and id */
mapi_object_init(obj_child);
mapi_object_set_session(obj_child, session);
@@ -692,6 +787,8 @@
retval = mapi_response->mapi_repl->error_code;
OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
+ OPENCHANGE_CHECK_NOTIFICATION(session, mapi_response);
+
talloc_free(mapi_response);
talloc_free(mem_ctx);
@@ -781,6 +878,8 @@
retval = mapi_response->mapi_repl->error_code;
OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
+ OPENCHANGE_CHECK_NOTIFICATION(session, mapi_response);
+
if (PartialCompletion) {
*PartialCompletion = mapi_response->mapi_repl->u.mapi_DeleteFolder.PartialCompletion;
}
@@ -889,6 +988,8 @@
retval = mapi_response->mapi_repl->error_code;
OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
+ OPENCHANGE_CHECK_NOTIFICATION(session[0], mapi_response);
+
talloc_free(mapi_response);
talloc_free(mem_ctx);
@@ -999,6 +1100,8 @@
retval = mapi_response->mapi_repl->error_code;
OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
+ OPENCHANGE_CHECK_NOTIFICATION(session[0], mapi_response);
+
talloc_free(mapi_response);
talloc_free(mem_ctx);
@@ -1089,6 +1192,8 @@
retval = mapi_response->mapi_repl->error_code;
OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
+ OPENCHANGE_CHECK_NOTIFICATION(session, mapi_response);
+
/* TODO: parse response */
talloc_free(mapi_response);
@@ -1097,3 +1202,76 @@
return MAPI_E_SUCCESS;
}
+/**
+ \details Hard delete the contents of a folder, including subfolders
+
+ This function empties (clears) the contents of a specified folder.
+
+ \param obj_folder the folder to empty
+
+ \return MAPI_E_SUCCESS on success, otherwise MAPI error.
+
+ \note Developers may also call GetLastError() to retrieve the last
+ MAPI error code. Possible MAPI error codes are:
+ - MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized
+ - MAPI_E_INVALID_PARAMETER: obj_folder is not valid
+ - MAPI_E_CALL_FAILED: A network problem was encountered during the
+ transaction
+
+ \sa DeleteFolder, EmptyFolder
+*/
+_PUBLIC_ enum MAPISTATUS HardDeleteMessagesAndSubfolders(mapi_object_t *obj_folder)
+{
+ struct mapi_request *mapi_request;
+ struct mapi_response *mapi_response;
+ struct EcDoRpc_MAPI_REQ *mapi_req;
+ struct HardDeleteMessagesAndSubfolders_req request;
+ struct mapi_session *session;
+ NTSTATUS status;
+ enum MAPISTATUS retval;
+ uint32_t size;
+ TALLOC_CTX *mem_ctx;
+
+ /* Sanity checks */
+ OPENCHANGE_RETVAL_IF(!global_mapi_ctx, MAPI_E_NOT_INITIALIZED, NULL);
+ OPENCHANGE_RETVAL_IF(!obj_folder, MAPI_E_INVALID_PARAMETER, NULL);
+ session = mapi_object_get_session(obj_folder);
+ OPENCHANGE_RETVAL_IF(!session, MAPI_E_INVALID_PARAMETER, NULL);
+
+ mem_ctx = talloc_named(NULL, 0, "HardDeleteMessagesAndSubfolders");
+ size = 0;
+
+ /* Fill the EmptyFolder operation */
+ request.WantAsynchronous = 0x0;
+ size += sizeof (uint8_t);
+
+ request.WantDeleteAssociated = 0x0;
+ size += sizeof (uint8_t);
+
+ /* Fill the MAPI_REQ request */
+ mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ);
+ mapi_req->opnum = op_MAPI_HardDeleteMessagesAndSubfolders;
+ mapi_req->logon_id = mapi_object_get_logon_id(obj_folder);
+ mapi_req->handle_idx = 0;
+ mapi_req->u.mapi_HardDeleteMessagesAndSubfolders = 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);
+ mapi_request->length = size;
+ mapi_request->mapi_req = mapi_req;
+ mapi_request->handles = talloc_array(mem_ctx, uint32_t, 1);
+ mapi_request->handles[0] = mapi_object_get_handle(obj_folder);
+
+ status = emsmdb_transaction(session->emsmdb->ctx, mapi_request, &mapi_response);
+ OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx);
+ OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx);
+ retval = mapi_response->mapi_repl->error_code;
+ OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
+
+ talloc_free(mapi_response);
+ talloc_free(mem_ctx);
+
+ return MAPI_E_SUCCESS;
+}
Modified: trunk/openchange/libmapi/IMAPIProp.c
===================================================================
--- trunk/openchange/libmapi/IMAPIProp.c 2009-04-30 18:06:45 UTC (rev 2733)
+++ trunk/openchange/libmapi/IMAPIProp.c 2009-04-30 18:06:50 UTC (rev 2734)
@@ -135,6 +135,8 @@
OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx);
retval = mapi_response->mapi_repl->error_code;
OPENCHANGE_RETVAL_IF((retval && retval != MAPI_W_ERRORS_RETURNED), retval, mem_ctx);
+
+ OPENCHANGE_CHECK_NOTIFICATION(session, mapi_response);
/* Read the SPropValue array from data blob.
fixme: replace the memory context by the object one.
@@ -254,6 +256,8 @@
retval = mapi_response->mapi_repl->error_code;
OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
+ OPENCHANGE_CHECK_NOTIFICATION(session, mapi_response);
+
if (named == true) {
mapi_nameid_unmap_SPropValue(nameid, lpProps, PropCount);
}
@@ -347,6 +351,8 @@
retval = mapi_response->mapi_repl->error_code;
OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
+ OPENCHANGE_CHECK_NOTIFICATION(session[0], mapi_response);
+
talloc_free(mapi_response);
talloc_free(mem_ctx);
@@ -417,6 +423,8 @@
retval = mapi_response->mapi_repl->error_code;
OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
+ OPENCHANGE_CHECK_NOTIFICATION(session, mapi_response);
+
/* Get the repsonse */
proptags->cValues = mapi_response->mapi_repl->u.mapi_GetPropList.count;
if (proptags->cValues) {
@@ -506,6 +514,8 @@
retval = mapi_response->mapi_repl->error_code;
OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
+ OPENCHANGE_CHECK_NOTIFICATION(session, mapi_response);
+
reply = &mapi_response->mapi_repl->u.mapi_GetPropsAll;
properties->cValues = reply->properties.cValues;
properties->lpProps = talloc_steal((TALLOC_CTX *)session, reply->properties.lpProps);
@@ -584,13 +594,127 @@
retval = mapi_response->mapi_repl->error_code;
OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
+ OPENCHANGE_CHECK_NOTIFICATION(session, mapi_response);
+
talloc_free(mapi_response);
talloc_free(mem_ctx);
return MAPI_E_SUCCESS;
}
+/**
+ \details Set one or more properties on a given object without
+ invoking replication.
+ This function sets one or more properties on a specified object. It
+ is the same as SetProps, except if the object is a folder, where
+ this function does not result in folder properties being replicated.
+
+ \param obj the object to set properties on
+ \param lpProps the list of properties to set
+ \param PropCount the number of properties
+
+ \return MAPI_E_SUCCESS on success, otherwise MAPI error.
+
+ \note Developers may also call GetLastError() to retrieve the last
+ MAPI error code. Possible MAPI error codes are:
+ - MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized
+ - MAPI_E_INVALID_PARAMETER: obj is not valid
+ - MAPI_E_CALL_FAILED: A network problem was encountered during the
+ transaction
+
+ \sa SetProps, DeletePropertiesNoReplicate
+*/
+_PUBLIC_ enum MAPISTATUS SetPropertiesNoReplicate(mapi_object_t *obj,
+ struct SPropValue *lpProps,
+ unsigned long PropCount)
+{
+ TALLOC_CTX *mem_ctx;
+ struct mapi_request *mapi_request;
+ struct mapi_response *mapi_response;
+ struct EcDoRpc_MAPI_REQ *mapi_req;
+ struct SetPropertiesNoReplicate_req request;
+ struct mapi_session *session;
+ struct mapi_nameid *nameid;
+ struct SPropTagArray *SPropTagArray = NULL;
+ NTSTATUS status;
+ enum MAPISTATUS retval;
+ uint32_t size = 0;
+ unsigned long i;
+ struct mapi_SPropValue *mapi_props;
+ bool named = false;
+
+ /* Sanity checks */
+ OPENCHANGE_RETVAL_IF(!global_mapi_ctx, MAPI_E_NOT_INITIALIZED, NULL);
+ OPENCHANGE_RETVAL_IF(!obj, MAPI_E_INVALID_PARAMETER, NULL);
+
+ session = mapi_object_get_session(obj);
+ OPENCHANGE_RETVAL_IF(!session, MAPI_E_INVALID_PARAMETER, NULL);
+
+ mem_ctx = talloc_named(NULL, 0, "SetPropertiesNoReplicate");
+ size = 0;
+
+ /* Named property mapping */
+ nameid = mapi_nameid_new(mem_ctx);
+ retval = mapi_nameid_lookup_SPropValue(nameid, lpProps, PropCount);
+ if (retval == MAPI_E_SUCCESS) {
+ named = true;
+ SPropTagArray = talloc_zero(mem_ctx, struct SPropTagArray);
+ retval = GetIDsFromNames(obj, nameid->count, nameid->nameid, 0, &SPropTagArray);
+ OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
+ mapi_nameid_map_SPropValue(nameid, lpProps, PropCount, SPropTagArray);
+ MAPIFreeBuffer(SPropTagArray);
+ }
+ errno = 0;
+
+ /* build the array */
+ request.values.lpProps = talloc_array(mem_ctx, struct mapi_SPropValue, PropCount);
+ mapi_props = request.values.lpProps;
+ for (i = 0; i < PropCount; i++) {
+ size += cast_mapi_SPropValue(&mapi_props[i], &lpProps[i]);
+ size += sizeof(uint32_t);
+ }
+
+ request.values.cValues = PropCount;
+ size += sizeof(uint16_t);
+
+ /* add the size of the subcontext that will be added on ndr layer */
+ size += sizeof(uint16_t);
+
+ /* Fill the MAPI_REQ request */
+ mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ);
+ mapi_req->opnum = op_MAPI_SetPropertiesNoReplicate;
+ mapi_req->logon_id = mapi_object_get_logon_id(obj);
+ mapi_req->handle_idx = 0;
+ mapi_req->u.mapi_SetPropertiesNoReplicate = 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);
+ mapi_request->length = size;
+ mapi_request->mapi_req = mapi_req;
+ mapi_request->handles = talloc_array(mem_ctx, uint32_t, 1);
+ mapi_request->handles[0] = mapi_object_get_handle(obj);
+
+ status = emsmdb_transaction(session->emsmdb->ctx, mapi_request, &mapi_response);
+ OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx);
+ OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx);
+ retval = mapi_response->mapi_repl->error_code;
+ OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
+
+ if (named == true) {
+ mapi_nameid_unmap_SPropValue(nameid, lpProps, PropCount);
+ }
+ talloc_free(nameid);
+
+ talloc_free(mapi_response);
+ talloc_free(mem_ctx);
+
+ return MAPI_E_SUCCESS;
+}
+
+
/**
\details Deletes property values from an object without invoking
replication.
@@ -660,6 +784,8 @@
retval = mapi_response->mapi_repl->error_code;
OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
+ OPENCHANGE_CHECK_NOTIFICATION(session, mapi_response);
+
talloc_free(mapi_response);
talloc_free(mem_ctx);
@@ -746,6 +872,8 @@
retval = mapi_response->mapi_repl->error_code;
OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
+ OPENCHANGE_CHECK_NOTIFICATION(session, mapi_response);
+
/* Fill in count */
reply = &mapi_response->mapi_repl->u.mapi_GetNamesFromIDs;
*count = reply->count;
@@ -867,6 +995,8 @@
retval = mapi_response->mapi_repl->error_code;
OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
+ OPENCHANGE_CHECK_NOTIFICATION(session, mapi_response);
+
/* Fill the SPropTagArray */
proptags[0]->cValues = mapi_response->mapi_repl->u.mapi_GetIDsFromNames.count;
proptags[0]->aulPropTag = talloc_array((TALLOC_CTX *)proptags[0], uint32_t, proptags[0]->cValues);
@@ -968,6 +1098,8 @@
retval = mapi_response->mapi_repl->error_code;
OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
+ OPENCHANGE_CHECK_NOTIFICATION(session, mapi_response);
+
/* Fill [out] parameters */
reply = &mapi_response->mapi_repl->u.mapi_QueryNamedProperties;
@@ -1079,6 +1211,8 @@
retval = mapi_response->mapi_repl->error_code;
OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
+ OPENCHANGE_CHECK_NOTIFICATION(session[0], mapi_response);
+
if (problemCount) {
*problemCount = mapi_response->mapi_repl->u.mapi_CopyProperties.PropertyProblemCount;
*problems = talloc_array((TALLOC_CTX *)session[0], struct PropertyProblem, *problemCount);
@@ -1195,6 +1329,8 @@
retval = mapi_response->mapi_repl->error_code;
OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
+ OPENCHANGE_CHECK_NOTIFICATION(session[0], mapi_response);
+
if (problemCount) {
*problemCount = mapi_response->mapi_repl->u.mapi_CopyTo.PropertyProblemCount;
*problems = talloc_array((TALLOC_CTX *)session[0], struct PropertyProblem, *problemCount);
Modified: trunk/openchange/libmapi/IMAPISession.c
===================================================================
--- trunk/openchange/libmapi/IMAPISession.c 2009-04-30 18:06:45 UTC (rev 2733)
+++ trunk/openchange/libmapi/IMAPISession.c 2009-04-30 18:06:50 UTC (rev 2734)
@@ -29,6 +29,96 @@
*/
+static enum MAPISTATUS FindGoodServer(struct mapi_session *session, const char *legacyDN, bool server)
+{
+ enum MAPISTATUS retval;
+ struct nspi_context *nspi;
+ struct StringsArray_r pNames;
+ struct SRowSet *SRowSet;
+ struct SPropTagArray *SPropTagArray = NULL;
+ struct SPropTagArray *MId_array;
+ struct StringArray_r *MVszA = NULL;
+ const char *binding = NULL;
+ char *HomeMDB = NULL;
+ char *server_dn;
+ int i;
+
+ /* Sanity checks */
+ OPENCHANGE_RETVAL_IF(!session, MAPI_E_NOT_INITIALIZED, NULL);
+ OPENCHANGE_RETVAL_IF(!session->nspi->ctx, MAPI_E_END_OF_SESSION, NULL);
+ OPENCHANGE_RETVAL_IF(!legacyDN, MAPI_E_INVALID_PARAMETER, NULL);
+
+ nspi = (struct nspi_context *) session->nspi->ctx;
+
+ if (server == false) {
+ /* Step 1. Retrieve a MID for our legacyDN */
+ pNames.Count = 0x1;
+ pNames.Strings = (const char **) talloc_array(nspi->mem_ctx, char **, 1);
+ pNames.Strings[0] = (const char *) talloc_strdup(pNames.Strings, legacyDN);
+
+ MId_array = talloc_zero(nspi->mem_ctx, struct SPropTagArray);
+ retval = nspi_DNToMId(nspi, &pNames, &MId_array);
+ MAPIFreeBuffer(pNames.Strings);
+ OPENCHANGE_RETVAL_IF(retval, retval, NULL);
+
+ /* Step 2. Retrieve the Server DN associated to this MId */
+ SRowSet = talloc_zero(nspi->mem_ctx, struct SRowSet);
+ SPropTagArray = set_SPropTagArray(nspi->mem_ctx, 0x1, PR_EMS_AB_HOME_MDB);
+ retval = nspi_GetProps(nspi, SPropTagArray, MId_array, &SRowSet);
+ MAPIFreeBuffer(SPropTagArray);
+ MAPIFreeBuffer(MId_array);
+ OPENCHANGE_RETVAL_IF(retval, retval, NULL);
+
+ HomeMDB = (char *)find_SPropValue_data(&(SRowSet->aRow[0]), PR_EMS_AB_HOME_MDB);
+ OPENCHANGE_RETVAL_IF(!HomeMDB, MAPI_E_NOT_FOUND, SRowSet);
+ server_dn = x500_truncate_dn_last_elements(nspi->mem_ctx, HomeMDB, 1);
+ MAPIFreeBuffer(SRowSet);
+ } else {
+ server_dn = talloc_strdup(nspi->mem_ctx, legacyDN);
+ }
+
+ /* Step 3. Retrieve the MId for this server DN */
+ pNames.Count = 0x1;
+ pNames.Strings = (const char **) talloc_array(nspi->mem_ctx, char **, 1);
+ pNames.Strings[0] = (const char *) talloc_strdup(pNames.Strings, server_dn);
+ MId_array = talloc_zero(nspi->mem_ctx, struct SPropTagArray);
+ retval = nspi_DNToMId(nspi, &pNames, &MId_array);
+ MAPIFreeBuffer(pNames.Strings);
+ OPENCHANGE_RETVAL_IF(retval, retval, server_dn);
+
+ /* Step 4. Retrieve the binding strings associated to this DN */
+ SRowSet = talloc_zero(nspi->mem_ctx, struct SRowSet);
+ SPropTagArray = set_SPropTagArray(nspi->mem_ctx, 0x1, PR_EMS_AB_NETWORK_ADDRESS);
+ retval = nspi_GetProps(nspi, SPropTagArray, MId_array, &SRowSet);
+ MAPIFreeBuffer(SPropTagArray);
+ MAPIFreeBuffer(MId_array);
+ MAPIFreeBuffer(server_dn);
+ OPENCHANGE_RETVAL_IF(retval, retval, SRowSet);
+
+ /* Step 5. Extract host from ncacn_ip_tcp binding string */
+ MVszA = (struct StringArray_r *) find_SPropValue_data(&(SRowSet->aRow[0]), PR_EMS_AB_NETWORK_ADDRESS);
+ OPENCHANGE_RETVAL_IF(!MVszA, MAPI_E_NOT_FOUND, SRowSet);
+ for (i = 0; i != MVszA->cValues; i++) {
+ if (!strncasecmp(MVszA->lppszA[i], "ncacn_ip_tcp:", 13)) {
+ binding = MVszA->lppszA[i] + 13;
+ break;
+ }
+ }
+ MAPIFreeBuffer(SRowSet);
+ OPENCHANGE_RETVAL_IF(!binding, MAPI_E_NOT_FOUND, NULL);
+
+ /* Step 6. Close the existing session and initiates it again */
+ talloc_free(session->emsmdb);
+ session->emsmdb = talloc_zero(session, struct mapi_provider);
+ talloc_set_destructor((void *)session->emsmdb, (int (*)(void *))emsmdb_disconnect_dtor);
+ session->profile->server = talloc_strdup(session->profile, binding);
+ retval = Logon(session, session->emsmdb, PROVIDER_ID_EMSMDB);
+ OPENCHANGE_RETVAL_IF(retval, retval, NULL);
+
+ return MAPI_E_SUCCESS;
+}
+
+
/**
\details Open the Public Folder store
@@ -63,6 +153,7 @@
TALLOC_CTX *mem_ctx;
mapi_object_store_t *store;
uint8_t logon_id;
+ bool retry = false;
/* Sanity checks */
OPENCHANGE_RETVAL_IF(!global_mapi_ctx, MAPI_E_NOT_INITIALIZED, NULL);
@@ -73,6 +164,7 @@
retval = GetNewLogonId(session, &logon_id);
OPENCHANGE_RETVAL_IF(retval, MAPI_E_FAILONEPROVIDER, NULL);
+retry:
mem_ctx = talloc_named(NULL, 0, "OpenPublicFolder");
size = 0;
@@ -105,8 +197,17 @@
OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx);
OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx);
retval = mapi_response->mapi_repl->error_code;
+ if (retval == ecWrongServer && retry == false && mapi_response->mapi_repl->us.mapi_Logon.ServerName) {
+ retval = FindGoodServer(session, mapi_response->mapi_repl->us.mapi_Logon.ServerName, true);
+ OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
+ talloc_free(mem_ctx);
+ retry = true;
+ goto retry;
+ }
OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
+ OPENCHANGE_CHECK_NOTIFICATION(session, mapi_response);
+
/* retrieve object session, handle and logon_id */
mapi_object_set_session(obj_store, session);
mapi_object_set_handle(obj_store, mapi_response->handles[0]);
@@ -218,6 +319,7 @@
mapi_object_store_t *store;
char *mailbox;
uint8_t logon_id;
+ bool retry = false;
/* sanity checks */
OPENCHANGE_RETVAL_IF(!global_mapi_ctx, MAPI_E_NOT_INITIALIZED, NULL);
@@ -228,6 +330,7 @@
retval = GetNewLogonId(session, &logon_id);
OPENCHANGE_RETVAL_IF(retval, MAPI_E_FAILONEPROVIDER, NULL);
+retry:
mem_ctx = talloc_named(NULL, 0, "OpenMsgStore");
size = 0;
@@ -268,8 +371,17 @@
OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx);
OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx);
retval = mapi_response->mapi_repl->error_code;
+ if (retval == ecWrongServer && retry == false) {
+ retval = FindGoodServer(session, mailbox, false);
+ OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
+ talloc_free(mem_ctx);
+ retry = true;
+ goto retry;
+ }
OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
+ OPENCHANGE_CHECK_NOTIFICATION(session, mapi_response);
+
/* set object session, handle and logon_id */
mapi_object_set_session(obj_store, session);
mapi_object_set_handle(obj_store, mapi_response->handles[0]);
Modified: trunk/openchange/libmapi/IMAPISupport.c
===================================================================
--- trunk/openchange/libmapi/IMAPISupport.c 2009-04-30 18:06:45 UTC (rev 2733)
+++ trunk/openchange/libmapi/IMAPISupport.c 2009-04-30 18:06:50 UTC (rev 2734)
@@ -37,11 +37,13 @@
\param obj the object to get notifications for
\param connection connection identifier for callabck function
- \param NotificationFlags mask for events to provide notifications for (see
- below)
+ \param NotificationFlags mask for events to provide notifications
+ for (see below)
\param WholeStore whether the scope for this notification is whole
database
\param notify_callback notification callback function.
+ \param private_data the data to be passed at the callback function
+ when invoked
The Notification Flags can take the following values:
- fnevCriticalError
@@ -71,7 +73,8 @@
_PUBLIC_ enum MAPISTATUS Subscribe(mapi_object_t *obj, uint32_t *connection,
uint16_t NotificationFlags,
bool WholeStore,
- mapi_notify_callback_t notify_callback)
+ mapi_notify_callback_t notify_callback,
+ void *private_data)
{
TALLOC_CTX *mem_ctx;
struct mapi_request *mapi_request;
@@ -153,6 +156,7 @@
notification->NotificationFlags = NotificationFlags;
notification->callback = notify_callback;
+ notification->private_data = private_data;
DLIST_ADD(notify_ctx->notifications, notification);
@@ -215,10 +219,8 @@
return MAPI_E_SUCCESS;
}
-
-static enum MAPISTATUS ProcessNotification(struct mapi_notify_ctx *notify_ctx,
- struct mapi_response *mapi_response,
- void *private_data)
+enum MAPISTATUS ProcessNotification(struct mapi_notify_ctx *notify_ctx,
+ struct mapi_response *mapi_response)
{
struct notifications *notification;
void *NotificationData;
@@ -228,6 +230,8 @@
for (i = 0; mapi_response->mapi_repl[i].opnum; i++) {
if (mapi_response->mapi_repl[i].opnum == op_MAPI_Notify) {
+ mapi_handle_t handle = mapi_response->mapi_repl[i].u.mapi_Notify.NotificationHandle;
+
switch(mapi_response->mapi_repl[i].u.mapi_Notify.NotificationType) {
case fnevNewMail:
case fnevMbit|fnevNewMail:
@@ -298,12 +302,14 @@
break;
}
notification = notify_ctx->notifications;
+
while (notification->ulConnection) {
- if (notification->NotificationFlags & mapi_response->mapi_repl[i].u.mapi_Notify.NotificationType) {
+ if ((notification->NotificationFlags & mapi_response->mapi_repl[i].u.mapi_Notify.NotificationType) &&
+ (handle == mapi_object_get_handle(&(notification->obj_notif)))) {
if (notification->callback) {
notification->callback(mapi_response->mapi_repl[i].u.mapi_Notify.NotificationType,
(void *)NotificationData,
- (void *)private_data);
+ notification->private_data);
}
}
notification = notification->next;
@@ -313,7 +319,45 @@
return MAPI_E_SUCCESS;
}
+/**
+ \details Force notification of pending events
+ This function force the server to send any pending notificaion and
+ process them. These MAPI notifications are next compared to the
+ registered ones and the callback specified in Subscribe() called if
+ it matches.
+
+ \return MAPI_E_SUCCESS on success, otherwise MAPI error.
+
+ \note Developers may also call GetLastError() to retrieve the last
+ MAPI error code. Possible MAPI error codes are:
+ - MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized
+ - MAPI_E_CALL_FAILED: A network problem was encountered during the
+ transaction
+
+ \sa RegisterNotification, Subscribe, Unsubscribe, GetLastError
+*/
+_PUBLIC_ enum MAPISTATUS DispatchNotifications(struct mapi_session *session)
+{
+ struct mapi_response *mapi_response;
+ enum MAPISTATUS retval;
+ NTSTATUS status;
+
+ /* sanity checks */
+ OPENCHANGE_RETVAL_IF(!global_mapi_ctx, MAPI_E_NOT_INITIALIZED, NULL);
+ OPENCHANGE_RETVAL_IF(!session, MAPI_E_INVALID_PARAMETER, NULL);
+ OPENCHANGE_RETVAL_IF(!session->notify_ctx, MAPI_E_INVALID_PARAMETER, NULL);
+
+ status = emsmdb_transaction_null((struct emsmdb_context *)session->emsmdb->ctx, &mapi_response);
+ if (!NT_STATUS_IS_OK(status))
+ return MAPI_E_CALL_FAILED;
+
+ retval = ProcessNotification(session->notify_ctx, mapi_response);
+ talloc_free(mapi_response);
+ return retval;
+}
+
+
/**
\details Wait for notifications and process them
@@ -366,7 +410,7 @@
if (!NT_STATUS_IS_OK(status)) {
err = -1;
} else {
- retval = ProcessNotification(notify_ctx, mapi_response, private_data);
+ retval = ProcessNotification(notify_ctx, mapi_response);
OPENCHANGE_RETVAL_IF(retval, retval, NULL);
}
}
Modified: trunk/openchange/libmapi/IMAPITable.c
===================================================================
--- trunk/openchange/libmapi/IMAPITable.c 2009-04-30 18:06:45 UTC (rev 2733)
+++ trunk/openchange/libmapi/IMAPITable.c 2009-04-30 18:06:50 UTC (rev 2734)
@@ -101,6 +101,8 @@
retval = mapi_response->mapi_repl->error_code;
OPENCHANGE_RETVAL_IF(retval && (retval != MAPI_W_ERRORS_RETURNED), retval, mem_ctx);
+ OPENCHANGE_CHECK_NOTIFICATION(session, mapi_response);
+
/* recopy property tags into table */
/* fixme: obj_table->private_data should be initialized during opening, not here */
if (obj_table->private_data == NULL) {
@@ -186,6 +188,8 @@
OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx);
retval = mapi_response->mapi_repl->error_code;
OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
+
+ OPENCHANGE_CHECK_NOTIFICATION(session, mapi_response);
if (Numerator) {
*Numerator = mapi_response->mapi_repl->u.mapi_QueryPosition.Numerator;
@@ -282,6 +286,8 @@
retval = mapi_response->mapi_repl->error_code;
OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
+ OPENCHANGE_CHECK_NOTIFICATION(session, mapi_response);
+
/* table contains mapitags from previous SetColumns */
table = (mapi_object_table_t *)obj_table->private_data;
OPENCHANGE_RETVAL_IF(!table, MAPI_E_INVALID_OBJECT, mem_ctx);
@@ -364,6 +370,8 @@
retval = mapi_response->mapi_repl->error_code;
OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
+ OPENCHANGE_CHECK_NOTIFICATION(session, mapi_response);
+
/* get columns SPropTagArray */
table = (mapi_object_table_t *)obj_table->private_data;
OPENCHANGE_RETVAL_IF(!table, MAPI_E_INVALID_OBJECT, mem_ctx);
@@ -460,6 +468,8 @@
retval = mapi_response->mapi_repl->error_code;
OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
+ OPENCHANGE_CHECK_NOTIFICATION(session, mapi_response);
+
reply = &mapi_response->mapi_repl->u.mapi_SeekRow;
*row = reply->RowsSought;
@@ -554,6 +564,8 @@
retval = mapi_response->mapi_repl->error_code;
OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
+ OPENCHANGE_CHECK_NOTIFICATION(session, mapi_response);
+
reply = &mapi_response->mapi_repl->u.mapi_SeekRowBookmark;
*row = reply->RowsSought;
@@ -648,6 +660,8 @@
retval = mapi_response->mapi_repl->error_code;
OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
+ OPENCHANGE_CHECK_NOTIFICATION(session, mapi_response);
+
talloc_free(mapi_response);
talloc_free(mem_ctx);
@@ -719,6 +733,8 @@
retval = mapi_response->mapi_repl->error_code;
OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
+ OPENCHANGE_CHECK_NOTIFICATION(session, mapi_response);
+
reply = &mapi_response->mapi_repl->u.mapi_CreateBookmark;
mapi_table = (mapi_object_table_t *)obj_table->private_data;
@@ -830,6 +846,8 @@
retval = mapi_response->mapi_repl->error_code;
OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
+ OPENCHANGE_CHECK_NOTIFICATION(session, mapi_response);
+
MAPIFreeBuffer(bookmark->bin.lpb);
DLIST_REMOVE(table->bookmark, bookmark);
@@ -918,6 +936,8 @@
retval = mapi_response->mapi_repl->error_code;
OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
+ OPENCHANGE_CHECK_NOTIFICATION(session, mapi_response);
+
talloc_free(mapi_response);
talloc_free(mem_ctx);
@@ -1046,6 +1066,8 @@
retval = mapi_response->mapi_repl->error_code;
OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
+ OPENCHANGE_CHECK_NOTIFICATION(session, mapi_response);
+
talloc_free(mapi_response);
talloc_free(mem_ctx);
@@ -1144,6 +1166,8 @@
retval = mapi_response->mapi_repl->error_code;
OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
+ OPENCHANGE_CHECK_NOTIFICATION(session, mapi_response);
+
if (TableStatus) {
reply = &mapi_response->mapi_repl->u.mapi_Restrict;
*TableStatus = reply->TableStatus;
@@ -1265,6 +1289,8 @@
retval = mapi_response->mapi_repl->error_code;
OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
+ OPENCHANGE_CHECK_NOTIFICATION(session, mapi_response);
+
/* table contains SPropTagArray from previous SetColumns call */
table = (mapi_object_table_t *)obj_table->private_data;
OPENCHANGE_RETVAL_IF(!table, MAPI_E_INVALID_OBJECT, mem_ctx);
@@ -1352,6 +1378,8 @@
retval = mapi_response->mapi_repl->error_code;
OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
+ OPENCHANGE_CHECK_NOTIFICATION(session, mapi_response);
+
/* Retrieve TableStatus */
reply = &mapi_response->mapi_repl->u.mapi_GetStatus;
*TableStatus = reply->TableStatus;
@@ -1424,6 +1452,8 @@
retval = mapi_response->mapi_repl->error_code;
OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
+ OPENCHANGE_CHECK_NOTIFICATION(session, mapi_response);
+
/* Retrieve TableStatus */
reply = &mapi_response->mapi_repl->u.mapi_Abort;
*TableStatus = reply->TableStatus;
@@ -1529,6 +1559,8 @@
retval = mapi_response->mapi_repl->error_code;
OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
+ OPENCHANGE_CHECK_NOTIFICATION(session, mapi_response);
+
/* table contains mapitags from previous SetColumns */
table = (mapi_object_table_t *)obj_table->private_data;
OPENCHANGE_RETVAL_IF(!table, MAPI_E_INVALID_OBJECT, mem_ctx);
@@ -1625,6 +1657,8 @@
retval = mapi_response->mapi_repl->error_code;
OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
+ OPENCHANGE_CHECK_NOTIFICATION(session, mapi_response);
+
/* Retrieve the RowCount */
reply = &mapi_response->mapi_repl->u.mapi_CollapseRow;
*rowCount = reply->CollapsedRowCount;
@@ -1718,6 +1752,8 @@
retval = mapi_response->mapi_repl->error_code;
OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
+ OPENCHANGE_CHECK_NOTIFICATION(session, mapi_response);
+
/* Retrieve the CollapseState */
reply = &mapi_response->mapi_repl->u.mapi_GetCollapseState;
CollapseState->cb = reply->CollapseState.cb;
@@ -1808,6 +1844,8 @@
retval = mapi_response->mapi_repl->error_code;
OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
+ OPENCHANGE_CHECK_NOTIFICATION(session, mapi_response);
+
reply = &mapi_response->mapi_repl->u.mapi_SetCollapseState;
mapi_table = (mapi_object_table_t *)obj_table->private_data;
Modified: trunk/openchange/libmapi/IMessage.c
===================================================================
--- trunk/openchange/libmapi/IMessage.c 2009-04-30 18:06:45 UTC (rev 2733)
+++ trunk/openchange/libmapi/IMessage.c 2009-04-30 18:06:50 UTC (rev 2734)
@@ -126,6 +126,8 @@
retval = mapi_response->mapi_repl->error_code;
OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
+ OPENCHANGE_CHECK_NOTIFICATION(session, mapi_response);
+
/* Set object session and handle */
mapi_object_set_session(obj_attach, session);
mapi_object_set_handle(obj_attach, mapi_response->handles[1]);
@@ -204,6 +206,8 @@
retval = mapi_response->mapi_repl->error_code;
OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
+ OPENCHANGE_CHECK_NOTIFICATION(session, mapi_response);
+
talloc_free(mapi_response);
talloc_free(mem_ctx);
@@ -283,6 +287,8 @@
retval = mapi_response->mapi_repl->error_code;
OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
+ OPENCHANGE_CHECK_NOTIFICATION(session, mapi_response);
+
/* Set object session and handle */
mapi_object_set_session(obj_table, session);
mapi_object_set_handle(obj_table, mapi_response->handles[mapi_response->mapi_repl->handle_idx]);
@@ -371,6 +377,8 @@
retval = mapi_response->mapi_repl->error_code;
OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
+ OPENCHANGE_CHECK_NOTIFICATION(session, mapi_response);
+
/* Set object session and handle */
mapi_object_set_session(obj_attach, session);
mapi_object_set_handle(obj_attach, mapi_response->handles[1]);
@@ -709,6 +717,8 @@
retval = mapi_response->mapi_repl->error_code;
OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
+ OPENCHANGE_CHECK_NOTIFICATION(session, mapi_response);
+
talloc_free(mapi_response);
talloc_free(mem_ctx);
@@ -790,6 +800,8 @@
retval = mapi_response->mapi_repl->error_code;
OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
+ OPENCHANGE_CHECK_NOTIFICATION(session, mapi_response);
+
/* Retrieve the recipients */
reply = &mapi_response->mapi_repl->u.mapi_ReadRecipients;
*RowCount = reply->RowCount;
@@ -865,6 +877,8 @@
retval = mapi_response->mapi_repl->error_code;
OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
+ OPENCHANGE_CHECK_NOTIFICATION(session, mapi_response);
+
talloc_free(mapi_response);
talloc_free(mem_ctx);
@@ -940,6 +954,8 @@
retval = mapi_response->mapi_repl->error_code;
OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
+ OPENCHANGE_CHECK_NOTIFICATION(session, mapi_response);
+
talloc_free(mapi_response);
talloc_free(mem_ctx);
@@ -1028,6 +1044,8 @@
retval = mapi_response->mapi_repl->error_code;
OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
+ OPENCHANGE_CHECK_NOTIFICATION(session[0], mapi_response);
+
talloc_free(mapi_response);
talloc_free(mem_ctx);
@@ -1118,6 +1136,8 @@
retval = mapi_response->mapi_repl->error_code;
OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
+ OPENCHANGE_CHECK_NOTIFICATION(session[0], mapi_response);
+
/* store the message_id */
mapi_object_set_id(obj_message, mapi_response->mapi_repl->u.mapi_SaveChangesMessage.MessageId);
@@ -1177,6 +1197,8 @@
retval = mapi_response->mapi_repl->error_code;
OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
+ OPENCHANGE_CHECK_NOTIFICATION(session, mapi_response);
+
/* Retrieve reply parameters */
reply = &mapi_response->mapi_repl->u.mapi_TransportSend;
if (!reply->NoPropertiesReturned) {
@@ -1306,6 +1328,8 @@
retval = mapi_response->mapi_repl->error_code;
OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
+ OPENCHANGE_CHECK_NOTIFICATION(session[0], mapi_response);
+
talloc_free(mapi_response);
talloc_free(mem_ctx);
@@ -1438,6 +1462,8 @@
retval = mapi_response->mapi_repl->error_code;
OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
+ OPENCHANGE_CHECK_NOTIFICATION(session, mapi_response);
+
/* Set object session and handle */
mapi_object_set_session(obj_embeddedmsg, session);
mapi_object_set_handle(obj_embeddedmsg, mapi_response->handles[1]);
Modified: trunk/openchange/libmapi/IMsgStore.c
===================================================================
--- trunk/openchange/libmapi/IMsgStore.c 2009-04-30 18:06:45 UTC (rev 2733)
+++ trunk/openchange/libmapi/IMsgStore.c 2009-04-30 18:06:50 UTC (rev 2734)
@@ -99,6 +99,8 @@
retval = mapi_response->mapi_repl->error_code;
OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
+ OPENCHANGE_CHECK_NOTIFICATION(session, mapi_response);
+
/* Set object session, id and handle */
mapi_object_set_session(obj_folder, session);
mapi_object_set_id(obj_folder, id_folder);
@@ -187,6 +189,8 @@
retval = mapi_response->mapi_repl->error_code;
OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
+ OPENCHANGE_CHECK_NOTIFICATION(session[0], mapi_response);
+
*IsGhosted = mapi_response->mapi_repl->u.mapi_PublicFolderIsGhosted.IsGhosted;
talloc_free(mapi_response);
@@ -272,6 +276,8 @@
retval = mapi_response->mapi_repl->error_code;
OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
+ OPENCHANGE_CHECK_NOTIFICATION(session, mapi_response);
+
/* Set object session and handle */
mapi_object_set_session(obj_child, session);
mapi_object_set_handle(obj_child, mapi_response->handles[1]);
@@ -292,7 +298,9 @@
\param obj_folder the destination folder
\param lpszMessageClass the message class the folder will receive
- \note Developers may also call GetLastError() to retrieve the last
+ \return MAPI_E_SUCCESS on success, otherwise MAPI error.
+
+ \note Developers may also call GetLastError() to retrieve the last
MAPI error code. Possible MAPI error codes are:
- MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized
- MAPI_E_CALL_FAILED: A network problem was encountered during the
@@ -353,6 +361,8 @@
retval = mapi_response->mapi_repl->error_code;
OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
+ OPENCHANGE_CHECK_NOTIFICATION(session, mapi_response);
+
talloc_free(mapi_response);
talloc_free(mem_ctx);
@@ -439,6 +449,8 @@
retval = mapi_response->mapi_repl->error_code;
OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
+ OPENCHANGE_CHECK_NOTIFICATION(session, mapi_response);
+
*id_folder = mapi_response->mapi_repl->u.mapi_GetReceiveFolder.folder_id;
talloc_free(mapi_response);
@@ -459,6 +471,8 @@
Developers are required to call MAPIFreeBuffer(SRowSet.aRow) when
they don't need the folder table data anymore.
+ \return MAPI_E_SUCCESS on success, otherwise MAPI error.
+
\note Developers may also call GetLastError() to retrieve the last
MAPI error code. Possible MAPI error codes are:
- MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized
@@ -511,6 +525,8 @@
retval = mapi_response->mapi_repl->error_code;
OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
+ OPENCHANGE_CHECK_NOTIFICATION(session, mapi_response);
+
reply = &mapi_response->mapi_repl->u.mapi_GetReceiveFolderTable;
/* Retrieve the ReceiveFolderTable entries */
@@ -608,6 +624,8 @@
retval = mapi_response->mapi_repl->error_code;
OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
+ OPENCHANGE_CHECK_NOTIFICATION(session, mapi_response);
+
/* Retrieve the FolderId parameter */
reply = &mapi_response->mapi_repl->u.mapi_GetTransportFolder;
*FolderId = reply->FolderId;
@@ -704,6 +722,8 @@
retval = mapi_response->mapi_repl->error_code;
OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
+ OPENCHANGE_CHECK_NOTIFICATION(session, mapi_response);
+
/* Retrieve GetOwningServers response */
response = mapi_response->mapi_repl->u.mapi_GetOwningServers;
@@ -727,16 +747,22 @@
/**
- \details Gets the current store state for the loggued user
+ \details Gets the current store state for the logged in user
+ This operation must be performed against a user store (not against
+ a Public Folder store). The StoreState will have the
+ STORE_HAS_SEARCHES flag set if there are any active search folders.
+ There are (currently) no other flags in the StoreState.
+
\param obj_store the store object
- \param StoreState pointer on the store state returned by the server
+ \param StoreState pointer to the store state returned by the server
\return MAPI_E_SUCCESS on success, otherwise MAPI error.
\note Developers may also call GetLastError() to retrieve the last
MAPI error code. Possible MAPI error codes are:
- MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized
+ - MAPI_E_INVALID_PARAMETER: obj_store or StoreState are not valid
- MAPI_E_CALL_FAILED: A network problem was encountered during the
transaction
*/
@@ -784,6 +810,8 @@
retval = mapi_response->mapi_repl->error_code;
OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
+ OPENCHANGE_CHECK_NOTIFICATION(session, mapi_response);
+
/* Retrieve the StoreState */
*StoreState = mapi_response->mapi_repl->u.mapi_GetStoreState.StoreState;
@@ -825,3 +853,85 @@
return MAPI_E_SUCCESS;
}
+
+
+/**
+ \details Notify the store of a new message to be processed
+
+ \param obj_folder the folder that the message is in
+ \param obj_msg the message to be processed
+ \param MessageClass the message class of the message to be processed
+ \param MessageFlags the message flags on the message
+
+ \return MAPI_E_SUCCESS on success, otherwise MAPI error.
+
+ \note Developers may also call GetLastError() to retrieve the last
+ MAPI error code. Possible MAPI error codes are:
+ - MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized
+ - MAPI_E_INVALID_PARAMETER: one the parameters is invalid
+ - MAPI_E_CALL_FAILED: A network problem was encountered during the
+ transaction
+
+ \sa GetReceiveFolder, GetReceiveFolderTable
+ */
+_PUBLIC_ enum MAPISTATUS TransportNewMail(mapi_object_t *obj_folder, mapi_object_t *obj_msg,
+ const char *MessageClass, uint32_t MessageFlags)
+{
+ struct mapi_request *mapi_request;
+ struct mapi_response *mapi_response;
+ struct EcDoRpc_MAPI_REQ *mapi_req;
+ struct TransportNewMail_req request;
+ struct mapi_session *session;
+ NTSTATUS status;
+ enum MAPISTATUS retval;
+ uint32_t size;
+ TALLOC_CTX *mem_ctx;
+
+ /* Sanity checks */
+ OPENCHANGE_RETVAL_IF(!global_mapi_ctx, MAPI_E_NOT_INITIALIZED, NULL);
+ OPENCHANGE_RETVAL_IF(!obj_folder, MAPI_E_INVALID_PARAMETER, NULL);
+ OPENCHANGE_RETVAL_IF(!obj_msg, MAPI_E_INVALID_PARAMETER, NULL);
+ OPENCHANGE_RETVAL_IF(!MessageClass, MAPI_E_INVALID_PARAMETER, NULL);
+ session = mapi_object_get_session(obj_folder);
+ OPENCHANGE_RETVAL_IF(!session, MAPI_E_INVALID_PARAMETER, NULL);
+
+ mem_ctx = talloc_named(NULL, 0, "TransportNewMail");
+
+ /* Fill the TransportNewMail operation */
+ size = 0;
+ request.MessageId = mapi_object_get_id(obj_msg);
+ size += sizeof (uint64_t);
+ request.FolderId = mapi_object_get_id(obj_folder);
+ size += sizeof (uint64_t);
+ request.MessageClass = MessageClass;
+ size += strlen(MessageClass) + 1;
+ request.MessageFlags = MessageFlags;
+ size += sizeof(uint32_t);
+
+ /* Fill the MAPI_REQ request */
+ mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ);
+ mapi_req->opnum = op_MAPI_TransportNewMail;
+ mapi_req->logon_id = mapi_object_get_logon_id(obj_folder);
+ mapi_req->handle_idx = 0;
+ mapi_req->u.mapi_TransportNewMail = 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);
+ mapi_request->length = size;
+ mapi_request->mapi_req = mapi_req;
+ mapi_request->handles = talloc_array(mem_ctx, uint32_t, 1);
+ mapi_request->handles[0] = mapi_object_get_handle(obj_folder);
+
+ status = emsmdb_transaction(session->emsmdb->ctx, mapi_request, &mapi_response);
+ OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx);
+ OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx);
+ retval = mapi_response->mapi_repl->error_code;
+ OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
+
+ talloc_free(mapi_response);
+ talloc_free(mem_ctx);
+
+ return MAPI_E_SUCCESS;
+}
Modified: trunk/openchange/libmapi/IStoreFolder.c
===================================================================
--- trunk/openchange/libmapi/IStoreFolder.c 2009-04-30 18:06:45 UTC (rev 2733)
+++ trunk/openchange/libmapi/IStoreFolder.c 2009-04-30 18:06:50 UTC (rev 2734)
@@ -121,6 +121,8 @@
retval = mapi_response->mapi_repl->error_code;
OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
+ OPENCHANGE_CHECK_NOTIFICATION(session, mapi_response);
+
/* Set object session and handle */
mapi_object_set_session(obj_message, session);
mapi_object_set_handle(obj_message, mapi_response->handles[1]);
Modified: trunk/openchange/libmapi/IStream.c
===================================================================
--- trunk/openchange/libmapi/IStream.c 2009-04-30 18:06:45 UTC (rev 2733)
+++ trunk/openchange/libmapi/IStream.c 2009-04-30 18:06:50 UTC (rev 2734)
@@ -117,6 +117,8 @@
retval = mapi_response->mapi_repl->error_code;
OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
+ OPENCHANGE_CHECK_NOTIFICATION(session, mapi_response);
+
/* Set object session and handle */
mapi_object_set_session(obj_stream, session);
mapi_object_set_handle(obj_stream, mapi_response->handles[1]);
@@ -209,6 +211,8 @@
retval = mapi_response->mapi_repl->error_code;
OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
+ OPENCHANGE_CHECK_NOTIFICATION(session, mapi_response);
+
/* copy no more than sz_data into buffer */
*ByteRead = mapi_response->mapi_repl->u.mapi_ReadStream.data.length;
if (*ByteRead > 0) {
@@ -305,6 +309,8 @@
retval = mapi_response->mapi_repl->error_code;
OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
+ OPENCHANGE_CHECK_NOTIFICATION(session, mapi_response);
+
*WrittenSize = mapi_response->mapi_repl->u.mapi_WriteStream.WrittenSize;
talloc_free(mapi_response);
@@ -373,6 +379,8 @@
retval = mapi_response->mapi_repl->error_code;
OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
+ OPENCHANGE_CHECK_NOTIFICATION(session, mapi_response);
+
talloc_free(mapi_response);
talloc_free(mem_ctx);
@@ -439,6 +447,8 @@
retval = mapi_response->mapi_repl->error_code;
OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
+ OPENCHANGE_CHECK_NOTIFICATION(session, mapi_response);
+
*StreamSize = mapi_response->mapi_repl->u.mapi_GetStreamSize.StreamSize;
talloc_free(mapi_response);
@@ -530,6 +540,8 @@
retval = mapi_response->mapi_repl->error_code;
OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
+ OPENCHANGE_CHECK_NOTIFICATION(session, mapi_response);
+
*NewPosition = mapi_response->mapi_repl->u.mapi_SeekStream.NewPosition;
talloc_free(mapi_response);
@@ -603,6 +615,8 @@
retval = mapi_response->mapi_repl->error_code;
OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
+ OPENCHANGE_CHECK_NOTIFICATION(session, mapi_response);
+
talloc_free(mapi_response);
talloc_free(mem_ctx);
@@ -697,6 +711,8 @@
retval = mapi_response->mapi_repl->error_code;
OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
+ OPENCHANGE_CHECK_NOTIFICATION(session[0], mapi_response);
+
*ReadByteCount = mapi_response->mapi_repl->u.mapi_CopyToStream.ReadByteCount;
*WrittenByteCount = mapi_response->mapi_repl->u.mapi_CopyToStream.WrittenByteCount;
@@ -866,3 +882,171 @@
return MAPI_E_SUCCESS;
}
+
+/**
+ \details Clone a source stream to another stream
+
+ \param obj_src the source stream object
+ \param obj_dst the destination stream object
+
+ \return MAPI_E_SUCCESS on success, otherwise MAPI error.
+
+ \note Developers may also call GetLastError() to retrieve the last
+ MAPI error code. Possible MAPI error codes are:
+ - MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized
+ - MAPI_E_INVALID_PARAMETER: source or destination streams are not valid.
+ - MAPI_E_CALL_FAILED: A network problem was encountered during the
+ transaction
+
+ \sa OpenStream
+*/
+_PUBLIC_ enum MAPISTATUS CloneStream(mapi_object_t *obj_src, mapi_object_t *obj_dst)
+{
+ struct mapi_request *mapi_request;
+ struct mapi_response *mapi_response;
+ struct EcDoRpc_MAPI_REQ *mapi_req;
+ struct CloneStream_req request;
+ struct mapi_session *session;
+ NTSTATUS status;
+ enum MAPISTATUS retval;
+ TALLOC_CTX *mem_ctx;
+ uint32_t size;
+
+ /* Sanity Check */
+ OPENCHANGE_RETVAL_IF(!global_mapi_ctx, MAPI_E_NOT_INITIALIZED, NULL);
+ OPENCHANGE_RETVAL_IF(!obj_src, MAPI_E_INVALID_PARAMETER, NULL);
+ OPENCHANGE_RETVAL_IF(!obj_dst, MAPI_E_INVALID_PARAMETER, NULL);
+
+ session = mapi_object_get_session(obj_src);
+ OPENCHANGE_RETVAL_IF(!session, MAPI_E_INVALID_PARAMETER, NULL);
+
+ mem_ctx = talloc_named(NULL, 0, "CloneStream");
+ size = 0;
+
+ /* Fill the CloneStream operation */
+ request.handle_idx = 0x1; /* destionation */
+ size += sizeof (uint8_t);
+
+ /* Fill the MAPI_REQ request */
+ mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ);
+ mapi_req->opnum = op_MAPI_CloneStream;
+ mapi_req->logon_id = mapi_object_get_logon_id(obj_src);
+ mapi_req->handle_idx = 0;
+ mapi_req->u.mapi_CloneStream = 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] = 0xFFFFFFFF;
+
+ status = emsmdb_transaction(session->emsmdb->ctx, mapi_request, &mapi_response);
+ OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx);
+ OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx);
+ retval = mapi_response->mapi_repl->error_code;
+ OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
+
+ mapi_object_set_handle(obj_dst, mapi_response->handles[1]);
+ mapi_object_set_session(obj_dst, session);
+ mapi_object_set_logon_id(obj_dst, mapi_object_get_logon_id(obj_src));
+
+ talloc_free(mapi_response);
+ talloc_free(mem_ctx);
+
+ return MAPI_E_SUCCESS;
+}
+
+/**
+ \details Write and commit a buffer to the stream
+
+ This function writes and commits the contents of a DATA_BLOB to
+ the stream obj_stream.
+
+ \param obj_stream the opened stream object
+ \param blob the DATA_BLOB to write to the stream
+ \param WrittenSize the actual number of bytes written to the
+ stream
+
+ \return MAPI_E_SUCCESS on success, otherwise MAPI error.
+
+ \note Developers may also call GetLastError() to retrieve the last
+ MAPI error code. Possible MAPI error codes are:
+ - MAPI_E_NOT_INITIALIZED: MAPI subsystem has not been initialized
+ - MAPI_E_INVALID_PARAMETER: A problem occured obtaining the session
+ context, or the stream or blob were null.
+ - MAPI_E_CALL_FAILED: A network problem was encountered during the
+ transaction
+ - MAPI_E_TOO_BIG: the data blob was too large to process
+
+ \note The data size intended to be written to the stream should not
+ exceed a maximum size each time you call WriteStream. This size
+ depends on Exchange server version. However 0x1000 is known to be a
+ reliable write size value.
+
+ \sa WriteStream, CommitStream
+ */
+_PUBLIC_ enum MAPISTATUS WriteAndCommitStream(mapi_object_t *obj_stream, DATA_BLOB *blob, uint16_t *WrittenSize)
+{
+ struct mapi_request *mapi_request;
+ struct mapi_response *mapi_response;
+ struct EcDoRpc_MAPI_REQ *mapi_req;
+ struct WriteAndCommitStream_req request;
+ struct mapi_session *session;
+ NTSTATUS status;
+ enum MAPISTATUS retval;
+ TALLOC_CTX *mem_ctx;
+ uint32_t size;
+
+ /* Sanity Checks */
+ OPENCHANGE_RETVAL_IF(!global_mapi_ctx, MAPI_E_NOT_INITIALIZED, NULL);
+ OPENCHANGE_RETVAL_IF(!obj_stream, MAPI_E_INVALID_PARAMETER, NULL);
+ session = mapi_object_get_session(obj_stream);
+ OPENCHANGE_RETVAL_IF(!session, MAPI_E_INVALID_PARAMETER, NULL);
+ OPENCHANGE_RETVAL_IF(!blob, MAPI_E_INVALID_PARAMETER, NULL);
+ OPENCHANGE_RETVAL_IF(blob->length > 0x7000, MAPI_E_TOO_BIG, NULL);
+
+ mem_ctx = talloc_named(NULL, 0, "WriteAndCommitStream");
+
+ size = 0;
+
+ /* Fill the WriteStream operation */
+ request.data = *blob;
+ size += blob->length;
+ /* size for subcontext(2) */
+ size += 2;
+
+ /* Fill the MAPI_REQ request */
+ mapi_req = talloc_zero(mem_ctx, struct EcDoRpc_MAPI_REQ);
+ mapi_req->opnum = op_MAPI_WriteAndCommitStream;
+ mapi_req->logon_id = mapi_object_get_logon_id(obj_stream);
+ mapi_req->handle_idx = 0;
+ mapi_req->u.mapi_WriteAndCommitStream = 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);
+ mapi_request->length = size;
+ mapi_request->mapi_req = mapi_req;
+ mapi_request->handles = talloc_array(mem_ctx, uint32_t, 1);
+ mapi_request->handles[0] = mapi_object_get_handle(obj_stream);
+
+ status = emsmdb_transaction(session->emsmdb->ctx, mapi_request, &mapi_response);
+ OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx);
+ OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx);
+ retval = mapi_response->mapi_repl->error_code;
+ OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
+
+ *WrittenSize = mapi_response->mapi_repl->u.mapi_WriteAndCommitStream.WrittenSize;
+
+ talloc_free(mapi_response);
+ talloc_free(mem_ctx);
+
+ errno = 0;
+ return MAPI_E_SUCCESS;
+}
+
Modified: trunk/openchange/libmapi/IUnknown.c
===================================================================
--- trunk/openchange/libmapi/IUnknown.c 2009-04-30 18:06:45 UTC (rev 2733)
+++ trunk/openchange/libmapi/IUnknown.c 2009-04-30 18:06:50 UTC (rev 2734)
@@ -145,6 +145,8 @@
status = emsmdb_transaction(session->emsmdb->ctx, mapi_request, &mapi_response);
OPENCHANGE_RETVAL_IF(!NT_STATUS_IS_OK(status), MAPI_E_CALL_FAILED, mem_ctx);
+ OPENCHANGE_CHECK_NOTIFICATION(session, mapi_response);
+
talloc_free(mapi_response);
talloc_free(mem_ctx);
@@ -235,7 +237,9 @@
OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx);
retval = mapi_response->mapi_repl->error_code;
OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
-
+
+ OPENCHANGE_CHECK_NOTIFICATION(session, mapi_response);
+
long_term_id->DatabaseGuid = mapi_response->mapi_repl->u.mapi_LongTermIdFromId.LongTermId.DatabaseGuid;
for (i = 0; i < 6; ++i) {
long_term_id->GlobalCounter[i] = mapi_response->mapi_repl->u.mapi_LongTermIdFromId.LongTermId.GlobalCounter[i];
@@ -317,7 +321,9 @@
OPENCHANGE_RETVAL_IF(!mapi_response->mapi_repl, MAPI_E_CALL_FAILED, mem_ctx);
retval = mapi_response->mapi_repl->error_code;
OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
-
+
+ OPENCHANGE_CHECK_NOTIFICATION(session, mapi_response);
+
*id = mapi_response->mapi_repl->u.mapi_IdFromLongTermId.Id;
talloc_free(mapi_response);
Modified: trunk/openchange/libmapi/IXPLogon.c
===================================================================
--- trunk/openchange/libmapi/IXPLogon.c 2009-04-30 18:06:45 UTC (rev 2733)
+++ trunk/openchange/libmapi/IXPLogon.c 2009-04-30 18:06:50 UTC (rev 2734)
@@ -93,6 +93,8 @@
retval = mapi_response->mapi_repl->error_code;
OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
+ OPENCHANGE_CHECK_NOTIFICATION(session, mapi_response);
+
/* Retrieve Address Types */
response = &mapi_response->mapi_repl->u.mapi_AddressTypes;
*lpcAdrType = response->cValues;
@@ -163,9 +165,10 @@
retval = mapi_response->mapi_repl->error_code;
OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
+ OPENCHANGE_CHECK_NOTIFICATION(session, mapi_response);
+
talloc_free(mapi_response);
talloc_free(mem_ctx);
-
return MAPI_E_SUCCESS;
}
@@ -249,6 +252,8 @@
retval = mapi_response->mapi_repl->error_code;
OPENCHANGE_RETVAL_IF(retval, retval, mem_ctx);
+ OPENCHANGE_CHECK_NOTIFICATION(session, mapi_response);
+
talloc_free(mapi_response);
talloc_free(mem_ctx);
Modified: trunk/openchange/libmapi/conf/mapi-properties
===================================================================
--- trunk/openchange/libmapi/conf/mapi-properties 2009-04-30 18:06:45 UTC (rev 2733)
+++ trunk/openchange/libmapi/conf/mapi-properties 2009-04-30 18:06:50 UTC (rev 2734)
@@ -915,16 +915,17 @@
0x67830003 PR_SEARCH_FLAGS
0x67aa000b PR_ASSOCIATED
0x67f00102 PR_PROFILE_SECURE_MAILBOX
-0x6800001e PR_MAILBEAT_BOUNCE_SERVER
-0x68010040 PR_MAILBEAT_REQUEST_SENT
-0x6802001e PR_USENET_SITE_NAME
-0x68030040 PR_MAILBEAT_REQUEST_RECEIVED
-0x68040040 PR_MAILBEAT_REQUEST_PROCESSED
-0x68050003 PR_SHUTOFFQUOTA
-0x68060040 PR_MAILBEAT_REPLY_SENT
-0x68070040 PR_MAILBEAT_REPLY_SUBMIT
-0x68080040 PR_MAILBEAT_REPLY_RECEIVED
-0x68090040 PR_MAILBEAT_REPLY_PROCESSED
+0x6800001e PR_OAB_NAME
+0x68010003 PR_OAB_SEQUENCE
+0x6802001e PR_OAB_CONTAINER_GUID
+0x68030003 PR_OAB_MESSAGE_CLASS
+0x6804001e PR_OAB_DN
+0x68051003 PR_OAB_TRUNCATED_PROPS
+0x68060102 PR_OAB_SHA_HASH
+0x68070003 PR_OAB_LANGID
+0x68080003 PR_OAB_FILETYPE
+0x68090003 PR_OAB_COMPRESSED_SIZE
+0x680A0003 PR_OAB_FILE_SIZE
0x68340003 PR_VIEW_STYLE
0x683A0003 PR_VIEW_MAJORVERSION
0x6844101e PR_DELEGATES_DISPLAY_NAMES
Modified: trunk/openchange/libmapi/conf/mparse.pl
===================================================================
--- trunk/openchange/libmapi/conf/mparse.pl 2009-04-30 18:06:45 UTC (rev 2733)
+++ trunk/openchange/libmapi/conf/mparse.pl 2009-04-30 18:06:50 UTC (rev 2734)
@@ -532,6 +532,12 @@
mparse " return (e); \\";
mparse "} while (0);";
mparse "";
+ mparse "#define OPENCHANGE_CHECK_NOTIFICATION(s,r) \\";
+ mparse "do { \\";
+ mparse " if (s->notify_ctx) \\";
+ mparse " ProcessNotification(s->notify_ctx, r); \\";
+ mparse "} while (0);";
+ mparse "";
mparse "/* Status macros for MAPI */";
mparse "typedef unsigned long SCODE;";
mparse "";
Modified: trunk/openchange/libmapi/mapi_notification.h
===================================================================
--- trunk/openchange/libmapi/mapi_notification.h 2009-04-30 18:06:45 UTC (rev 2733)
+++ trunk/openchange/libmapi/mapi_notification.h 2009-04-30 18:06:50 UTC (rev 2734)
@@ -32,6 +32,7 @@
uint32_t NotificationFlags; /* events mask associated */
mapi_id_t parentID; /* parent EntryID == FID here */
mapi_notify_callback_t callback; /* callback to run when */
+ void *private_data; /* private data for the callback */
struct mapi_object obj_notif; /* notification object */
struct notifications *prev;
struct notifications *next;
Modified: trunk/openchange/libmapi/x500.c
===================================================================
--- trunk/openchange/libmapi/x500.c 2009-04-30 18:06:45 UTC (rev 2733)
+++ trunk/openchange/libmapi/x500.c 2009-04-30 18:06:50 UTC (rev 2734)
@@ -56,7 +56,41 @@
return str;
}
+
/**
+ \details Truncate a DN element
+
+ \param mem_ctx pointer to the memory context
+ \param dn pointer to a valid DN
+ \param elcount the number of elements to remove from the end of the
+ DN
+
+ \return pointer to an allocated substring on success, otherwise
+ NULL
+ */
+_PUBLIC_ char *x500_truncate_dn_last_elements(TALLOC_CTX *mem_ctx, const char *dn, uint32_t elcount)
+{
+ char *tmp_dn;
+ int i;
+
+ if ((dn == NULL) || (dn[0] == '\0') || !elcount) return NULL;
+
+ tmp_dn = talloc_strdup(mem_ctx, dn);
+ for (i = strlen(tmp_dn); i > 0; i--) {
+ if (tmp_dn[i] == '/') {
+ elcount -= 1;
+ if (elcount == 0) {
+ tmp_dn[i] = '\0';
+ return tmp_dn;
+ }
+ }
+ }
+
+ return NULL;
+}
+
+
+/**
* Retrieve the servername from a string
* We should definitively find a better way to handle this
*/
Modified: trunk/openchange/mapiproxy/dcesrv_mapiproxy.c
===================================================================
--- trunk/openchange/mapiproxy/dcesrv_mapiproxy.c 2009-04-30 18:06:45 UTC (rev 2733)
+++ trunk/openchange/mapiproxy/dcesrv_mapiproxy.c 2009-04-30 18:06:50 UTC (rev 2734)
@@ -176,7 +176,7 @@
static NTSTATUS mapiproxy_op_bind_proxy(struct dcesrv_call_state *dce_call, const struct dcesrv_interface *iface)
{
- NTSTATUS status;
+ NTSTATUS status = NT_STATUS_OK;
const struct ndr_interface_table *table;
struct dcesrv_mapiproxy_private *private;
bool delegated;
@@ -310,7 +310,7 @@
}
/* If remote connection bind/auth has been delayed */
- if (private->connected == false) {
+ if (private->connected == false && private->server_mode == false) {
status = mapiproxy_op_connect(dce_call, table, NULL);
if (!NT_STATUS_IS_OK(status)) {
Modified: trunk/openchange/torture/mapi_newmail.c
===================================================================
--- trunk/openchange/torture/mapi_newmail.c 2009-04-30 18:06:45 UTC (rev 2733)
+++ trunk/openchange/torture/mapi_newmail.c 2009-04-30 18:06:50 UTC (rev 2734)
@@ -98,11 +98,11 @@
/* newmail and created|modified object notifications in inbox */
ulEventMask = fnevObjectCreated;
- retval = Subscribe(&obj_inbox, &ulConnection, ulEventMask, false, (mapi_notify_callback_t)callback);
+ retval = Subscribe(&obj_inbox, &ulConnection, ulEventMask, false, (mapi_notify_callback_t)callback, (void*) &obj_store);
mapi_errstr("Subscribe", GetLastError());
ulEventMask = fnevNewMail;
- retval = Subscribe(&obj_inbox, &ulConnection, ulEventMask, false, (mapi_notify_callback_t)callback);
+ retval = Subscribe(&obj_inbox, &ulConnection, ulEventMask, false, (mapi_notify_callback_t)callback, (void*) &obj_store);
mapi_errstr("Subscribe", GetLastError());
Modified: trunk/openchange/utils/mapitest/mapitest_common.c
===================================================================
--- trunk/openchange/utils/mapitest/mapitest_common.c 2009-04-30 18:06:45 UTC (rev 2733)
+++ trunk/openchange/utils/mapitest/mapitest_common.c 2009-04-30 18:06:50 UTC (rev 2734)
@@ -369,6 +369,7 @@
struct SPropValue lpProp[3];
int i;
uint32_t format;
+ bool ret;
context = mt->priv;
@@ -377,19 +378,18 @@
retval = CreateFolder(&(context->obj_top_folder), FOLDER_GENERIC,
MT_DIRNAME_TEST, NULL,
OPEN_IF_EXISTS, &(context->obj_test_folder));
- if (GetLastError() != MAPI_E_SUCCESS) {
- mapitest_print(mt, "* %-35s: 0x%.8x\n", "Create the test folder", GetLastError());
+ if (retval != MAPI_E_SUCCESS) {
+ mapitest_print_retval(mt, "Create the test folder");
return false;
}
/* Create 5 test messages in the test folder with the same subject */
for (i = 0; i < 5; ++i) {
mapi_object_init(&(context->obj_test_msg[i]));
- retval = mapitest_common_message_create(mt, &(context->obj_test_folder),
+ ret = mapitest_common_message_create(mt, &(context->obj_test_folder),
&(context->obj_test_msg[i]), MT_MAIL_SUBJECT);
- if (GetLastError() != MAPI_E_SUCCESS) {
- mapitest_print(mt, "* %-35s: 0x%.8x\n", "Create test message", GetLastError());
- mapi_object_release(&(context->obj_test_folder));
+ if (! ret) {
+ mapitest_print(mt, "* %-35s\n", "Failed to create test message");
return false;
}
@@ -404,13 +404,11 @@
MAPIFreeBuffer((void *)body);
if (retval != MAPI_E_SUCCESS) {
mapitest_print(mt, "* %-35s: 0x%.8x\n", "Set props on message", GetLastError());
- mapi_object_release(&(context->obj_test_folder));
return false;
}
retval = SaveChangesMessage(&(context->obj_test_folder), &(context->obj_test_msg[i]), KeepOpenReadWrite);
if (retval != MAPI_E_SUCCESS) {
mapitest_print(mt, "* %-35s: 0x%.8x\n", "Save changes to message", GetLastError());
- mapi_object_release(&(context->obj_test_folder));
return false;
}
}
@@ -419,10 +417,10 @@
for (i = 5; i < 10; ++i) {
mapi_object_init(&(context->obj_test_msg[i]));
subject = talloc_asprintf(mt->mem_ctx, "[MT] Subject%i", i);
- retval = mapitest_common_message_create(mt, &(context->obj_test_folder),
+ ret = mapitest_common_message_create(mt, &(context->obj_test_folder),
&(context->obj_test_msg[i]), subject);
- if (GetLastError() != MAPI_E_SUCCESS) {
- mapitest_print(mt, "* %-35s: 0x%.8x\n", "Create test message", GetLastError());
+ if (! ret){
+ mapitest_print(mt, "* %-35s\n", "Failed to create test message");
return false;
}
@@ -465,13 +463,15 @@
{
bool ret = false;
struct mt_common_tf_ctx *context;
+ enum MAPISTATUS retval;
context = talloc(mt->mem_ctx, struct mt_common_tf_ctx);
mt->priv = context;
mapi_object_init(&(context->obj_store));
- OpenMsgStore(mt->session, &(context->obj_store));
- if (GetLastError() != MAPI_E_SUCCESS) {
+ retval = OpenMsgStore(mt->session, &(context->obj_store));
+ if (retval != MAPI_E_SUCCESS) {
+ mapitest_print_retval(mt, "Failed OpenMsgStore");
return false;
}
@@ -490,8 +490,9 @@
}
mapi_object_init(obj_htable);
- GetHierarchyTable(&(context->obj_top_folder), obj_htable, 0, count);
- if (GetLastError() != MAPI_E_SUCCESS) {
+ retval = GetHierarchyTable(&(context->obj_top_folder), obj_htable, 0, count);
+ if (retval != MAPI_E_SUCCESS) {
+ mapitest_print_retval(mt, "Failed GetHierarchyTable");
return false;
}
Modified: trunk/openchange/utils/mapitest/module.c
===================================================================
--- trunk/openchange/utils/mapitest/module.c 2009-04-30 18:06:45 UTC (rev 2733)
+++ trunk/openchange/utils/mapitest/module.c 2009-04-30 18:06:50 UTC (rev 2734)
@@ -95,6 +95,8 @@
mapitest_suite_add_test(suite, "MOVECOPY-MESSAGES", "Move or copy messages from a source to destination folder", mapitest_oxcfold_MoveCopyMessages);
mapitest_suite_add_test(suite, "MOVEFOLDER", "Move folder from source to destination", mapitest_oxcfold_MoveFolder);
mapitest_suite_add_test(suite, "COPYFOLDER", "Copy folder from source to destination", mapitest_oxcfold_CopyFolder);
+ mapitest_suite_add_test(suite, "HARDDELETEMESSAGES", "Hard delete messages", mapitest_oxcfold_HardDeleteMessages);
+ mapitest_suite_add_test(suite, "HARDDELETEMESSAGESANDSUBFOLDERS", "Hard delete messages and subfolders", mapitest_oxcfold_HardDeleteMessagesAndSubfolders);
mapitest_suite_register(mt, suite);
@@ -121,6 +123,7 @@
mapitest_suite_add_test(suite, "SET-SPOOLER", "Client intends to act as a mail spooler", mapitest_oxomsg_SetSpooler);
mapitest_suite_add_test(suite, "SPOOLER-LOCK-MESSAGE", "Lock the specified message for spooling", mapitest_oxomsg_SpoolerLockMessage);
mapitest_suite_add_test(suite, "TRANSPORT-SEND", "Sends the specified message object out for message delivery", mapitest_oxomsg_TransportSend);
+ mapitest_suite_add_test(suite, "TRANSPORT-NEW-MAIL", "Submit a new message for processing", mapitest_oxomsg_TransportNewMail);
mapitest_suite_add_test(suite, "GET-TRANSPORT-FOLDER", "Retrieve the temporary transport folder ID", mapitest_oxomsg_GetTransportFolder);
mapitest_suite_register(mt, suite);
@@ -208,10 +211,11 @@
mapitest_suite_add_test(suite, "GET-PROPLIST", "Retrieve the property list", mapitest_oxcprpt_GetPropList);
mapitest_suite_add_test(suite, "SET-PROPS", "Set a specific set of properties", mapitest_oxcprpt_SetProps);
mapitest_suite_add_test(suite, "DELETE-PROPS", "Delete a specific set of properties", mapitest_oxcprpt_DeleteProps);
- mapitest_suite_add_test(suite, "DELETE-PROPS-NOREPL", "Delete a specific set of properties (no replicate)", mapitest_oxcprpt_DeletePropertiesNoReplicate);
+ mapitest_suite_add_test(suite, "PROPS-NOREPLICATE", "Set / delete a specific set of properties (no replicate)", mapitest_oxcprpt_NoReplicate);
mapitest_suite_add_test(suite, "COPY-PROPS", "Copy a specified set of properties", mapitest_oxcprpt_CopyProps);
mapitest_suite_add_test(suite, "STREAM", "Test stream operations", mapitest_oxcprpt_Stream);
mapitest_suite_add_test(suite, "COPYTO", "Copy or move properties", mapitest_oxcprpt_CopyTo);
+ mapitest_suite_add_test(suite, "WRITE-COMMIT-STREAM", "Test atomic Write / Commit operation", mapitest_oxcprpt_WriteAndCommitStream);
mapitest_suite_add_test(suite, "COPYTO-STREAM", "Copy stream from source to desination stream", mapitest_oxcprpt_CopyToStream);
mapitest_suite_add_test(suite, "NAME-ID", "Convert between Names and IDs", mapitest_oxcprpt_NameId);
Modified: trunk/openchange/utils/mapitest/modules/module_oxcfold.c
===================================================================
--- trunk/openchange/utils/mapitest/modules/module_oxcfold.c 2009-04-30 18:06:45 UTC (rev 2733)
+++ trunk/openchange/utils/mapitest/modules/module_oxcfold.c 2009-04-30 18:06:50 UTC (rev 2734)
@@ -4,6 +4,7 @@
OpenChange Project - FOLDER OBJECT PROTOCOL operations
Copyright (C) Julien Kerihuel 2008
+ Copyright (C) Brad Hards 2009
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
@@ -596,7 +597,7 @@
/**
- \details Test the MoveCopyMessages (0x33) opetation.
+ \details Test the MoveCopyMessages (0x33) operation.
This function:
-# Log on the user private mailbox
@@ -946,3 +947,238 @@
return ret;
}
+
+/**
+ \details Test the HardDeleteMessages (0x91) operation.
+
+ This function:
+ -# Log on the user private mailbox
+ -# Open the Inbox folder (source)
+ -# Creates 3 sample messages
+ -# Hard delete the sample messages
+
+ \param mt pointer to the top-level mapitest structure
+
+ \return true on success, otherwise false
+ */
+_PUBLIC_ bool mapitest_oxcfold_HardDeleteMessages(struct mapitest *mt)
+{
+ enum MAPISTATUS retval;
+ bool ret = true;
+ mapi_object_t obj_store;
+ mapi_object_t obj_folder;
+ mapi_object_t obj_message;
+ mapi_object_t contents;
+ struct mapi_SRestriction res;
+ struct SPropTagArray *SPropTagArray;
+ struct SRowSet SRowSet;
+ mapi_id_array_t msg_id_array;
+ mapi_id_t msgid[50];
+ mapi_id_t id_folder;
+ uint32_t i;
+ uint32_t count = 0;
+
+ /* Step 1. Logon */
+ mapi_object_init(&obj_store);
+ retval = OpenMsgStore(mt->session, &obj_store);
+ mapitest_print_retval(mt, "OpenMsgStore");
+ if (retval != MAPI_E_SUCCESS) {
+ ret = false;
+ goto cleanup;
+ }
+
+ /* Step 2. Open Source Inbox folder */
+ mapi_object_init(&obj_folder);
+ retval = GetDefaultFolder(&obj_store, &id_folder, olFolderInbox);
+ mapitest_print_retval(mt, "GetDefaultFolder");
+ if (retval != MAPI_E_SUCCESS) {
+ ret = false;
+ goto cleanup;
+ }
+
+ retval = OpenFolder(&obj_store, id_folder, &obj_folder);
+ mapitest_print_retval(mt, "OpenFolder");
+ if (retval != MAPI_E_SUCCESS) {
+ ret = false;
+ goto cleanup;
+ }
+
+ mapi_object_init(&(contents));
+ GetContentsTable(&(obj_folder), &(contents), 0, &count);
+ mapitest_print_retval(mt, "GetContentsTable");
+ if (retval != MAPI_E_SUCCESS) {
+ ret = false;
+ goto cleanup;
+ }
+
+ /* Step 3. Create sample messages */
+ mapi_id_array_init(&msg_id_array);
+ for (i = 0; i < 3; i++) {
+ mapi_object_init(&obj_message);
+ ret = mapitest_common_message_create(mt, &obj_folder, &obj_message, MT_MAIL_SUBJECT);
+ if (!ret) {
+ mapitest_print(mt, "failed to create message %i\n", i);
+ ret = false;
+ goto cleanup;
+ }
+
+ retval = SaveChangesMessage(&obj_folder, &obj_message, KeepOpenReadOnly);
+ mapitest_print_retval(mt, "SaveChangesMessage");
+ if (retval != MAPI_E_SUCCESS) {
+ ret = false;
+ goto cleanup;
+ }
+ mapi_id_array_add_obj(&msg_id_array, &obj_message);
+ mapi_object_release(&obj_message);
+ }
+
+
+ /* Step 4. Apply a filter */
+ res.rt = RES_PROPERTY;
+ res.res.resProperty.relop = RES_PROPERTY;
+ res.res.resProperty.ulPropTag = PR_SUBJECT;
+ res.res.resProperty.lpProp.ulPropTag = PR_SUBJECT;
+ res.res.resProperty.lpProp.value.lpszA = MT_MAIL_SUBJECT;
+
+ retval = Restrict(&(contents), &res, NULL);
+ mapitest_print_retval(mt, "Restrict");
+ if (retval != MAPI_E_SUCCESS) {
+ ret = false;
+ goto cleanup;
+ }
+
+ /* Step 5. Get the filtered rows */
+ SPropTagArray = set_SPropTagArray(mt->mem_ctx, 0x1, PR_MID);
+ SetColumns(&(contents), SPropTagArray);
+ mapitest_print_retval(mt, "SetColumns");
+ MAPIFreeBuffer(SPropTagArray);
+
+ retval = QueryRows(&(contents), 50, TBL_NOADVANCE, &SRowSet);
+ mapitest_print_retval(mt, "QueryRows");
+ if ( (retval == MAPI_E_SUCCESS) && (SRowSet.cRows >= 0) ) {
+ for (i = 0; i < SRowSet.cRows; ++i) {
+ msgid[i] = SRowSet.aRow[i].lpProps[0].value.d;
+ }
+ mapitest_print(mt, "%i Messages created successfully\n", SRowSet.cRows);
+ }
+
+ /* Step 6. Delete Messages */
+ retval = HardDeleteMessage(&obj_folder, msgid, i);
+ mapitest_print_retval(mt, "HardDeleteMessage");
+ if (retval != MAPI_E_SUCCESS) {
+ ret = false;
+ goto cleanup;
+ }
+
+ /* Step 7. Check the restriction again */
+ retval = QueryRows(&(contents), 50, TBL_NOADVANCE, &SRowSet);
+ mapitest_print_retval(mt, "QueryRows");
+ if ( retval != MAPI_E_SUCCESS ) {
+ ret = false;
+ goto cleanup;
+ }
+
+ if (SRowSet.cRows == 0) {
+ mapitest_print(mt, "successfully deleted messages\n");
+ } else {
+ mapitest_print(mt, "failed to delete messages\n");
+ ret = false;
+ }
+
+cleanup:
+ /* Release */
+ mapi_object_release(&obj_folder);
+ mapi_object_release(&obj_store);
+
+ return ret;
+}
+
+/**
+ \details Test the HardDeleteMessagesAndSubfolder (0x92) operation.
+
+ This function:
+ -# Creates a filled test folder
+ -# Creates 2 subdirectories in the test folder
+ -# Hard deletes the sample messages and subdirectories
+
+ \param mt pointer to the top-level mapitest structure
+
+ \return true on success, otherwise false
+ */
+_PUBLIC_ bool mapitest_oxcfold_HardDeleteMessagesAndSubfolders(struct mapitest *mt)
+{
+ struct mt_common_tf_ctx *context;
+ enum MAPISTATUS retval;
+ bool ret = true;
+ mapi_object_t obj_htable;
+ mapi_object_t subfolder1;
+ mapi_object_t subfolder2;
+ uint32_t unread = 0;
+ uint32_t total = 0;
+
+ /* Step 1. Logon and create a filled test folder */
+ if (! mapitest_common_setup(mt, &obj_htable, NULL)) {
+ return false;
+ }
+
+ context = mt->priv;
+
+ /* Step 2. Create two subfolders */
+ mapi_object_init(&subfolder1);
+ retval = CreateFolder(&(context->obj_test_folder), FOLDER_GENERIC,
+ "SubFolder1", NULL /*folder comment*/,
+ OPEN_IF_EXISTS, &subfolder1);
+ mapi_object_release(&subfolder1);
+ mapitest_print_retval(mt, "Create Subfolder1");
+ if (retval != MAPI_E_SUCCESS) {
+ ret = false;
+ goto cleanup;
+ }
+
+ mapi_object_init(&subfolder2);
+ retval = CreateFolder(&(context->obj_test_folder), FOLDER_GENERIC,
+ "SubFolder2", NULL /*folder comment*/,
+ OPEN_IF_EXISTS, &subfolder2);
+ mapi_object_release(&subfolder2);
+ mapitest_print_retval(mt, "Create Subfolder2");
+ if (retval != MAPI_E_SUCCESS) {
+ ret = false;
+ goto cleanup;
+ }
+
+ retval = GetFolderItemsCount(&(context->obj_test_folder), &unread, &total);
+ mapitest_print_retval(mt, "GetFolderItemsCount");
+ if (retval != MAPI_E_SUCCESS) {
+ ret = false;
+ goto cleanup;
+ }
+ mapitest_print(mt, "* Folder count: %i (%i unread)\n", total, unread);
+
+ /* Step 3. Hard delete contents */
+ retval = HardDeleteMessagesAndSubfolders(&(context->obj_test_folder));
+ mapitest_print_retval(mt, "HardDeleteMessagesAndSubfolders");
+ if (retval != MAPI_E_SUCCESS) {
+ ret = false;
+ goto cleanup;
+ }
+
+ /* Step 4. Check successful deletion */
+ retval = GetFolderItemsCount(&(context->obj_test_folder), &unread, &total);
+ mapitest_print_retval(mt, "GetFolderItemsCount");
+ if (retval != MAPI_E_SUCCESS) {
+ ret = false;
+ goto cleanup;
+ }
+ mapitest_print(mt, "* Folder count: %i (%i unread)\n", total, unread);
+
+ if (total != 0 || unread != 0) {
+ ret = false;
+ }
+
+ cleanup:
+ /* Cleanup and release */
+ mapi_object_release(&obj_htable);
+ mapitest_common_cleanup(mt);
+
+ return ret;
+}
Modified: trunk/openchange/utils/mapitest/modules/module_oxcnotif.c
===================================================================
--- trunk/openchange/utils/mapitest/modules/module_oxcnotif.c 2009-04-30 18:06:45 UTC (rev 2733)
+++ trunk/openchange/utils/mapitest/modules/module_oxcnotif.c 2009-04-30 18:06:50 UTC (rev 2734)
@@ -78,7 +78,7 @@
}
/* Step 4. Subscribe for notifications */
- retval = Subscribe(&obj_store, &tcon, fnevObjectCopied, true, cb);
+ retval = Subscribe(&obj_store, &tcon, fnevObjectCopied, true, cb, NULL);
mapitest_print_retval(mt, "Subscribe");
if (retval != MAPI_E_SUCCESS) {
return false;
Modified: trunk/openchange/utils/mapitest/modules/module_oxcprpt.c
===================================================================
--- trunk/openchange/utils/mapitest/modules/module_oxcprpt.c 2009-04-30 18:06:45 UTC (rev 2733)
+++ trunk/openchange/utils/mapitest/modules/module_oxcprpt.c 2009-04-30 18:06:50 UTC (rev 2734)
@@ -4,7 +4,7 @@
OpenChange Project - PROPERTY AND STREAM OBJECT PROTOCOL operations
Copyright (C) Julien Kerihuel 2008
- Copyright (C) Brad Hards 2008
+ Copyright (C) Brad Hards 2008-2009
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
@@ -763,10 +763,10 @@
/**
- \details Test Stream operations. This test uses all related stream
+ \details Test Stream operations. This test uses related stream
operations: OpenStream (0x2b), SetStreamSize (0x2f), WriteStream
(0x2d), CommitStream (0x5d), ReadStream (0x2c), SeekStream (0x2e),
- LockRegionStream (0x5b) and UnlockRegionStream (0x5c)
+ LockRegionStream (0x5b), UnlockRegionStream (0x5c), CloneStream (0x3b)
This function:
-# Logon
@@ -786,6 +786,7 @@
-# Lock a range of the stream
-# TODO: test if the locking works
-# Unlock a range of the stream
+ -# Clone the stream
-# Delete the message;
\param mt pointer to the top-level mapitest structure
@@ -801,6 +802,7 @@
mapi_object_t obj_message;
mapi_object_t obj_attach;
mapi_object_t obj_stream;
+ mapi_object_t obj_stream_clone;
mapi_id_t id_folder;
DATA_BLOB data;
struct SPropValue attach[3];
@@ -1019,7 +1021,27 @@
ret = false;
}
- /* Step 16. Delete the message */
+ /* Step 16. Clone the stream */
+ mapi_object_init(&obj_stream_clone);
+ retval = CloneStream(&obj_stream, &obj_stream_clone);
+ mapitest_print_retval(mt, "CloneStream");
+ if (retval != MAPI_E_SUCCESS) {
+ ret = false;
+ }
+
+ /* Step 17. Test the clone */
+ retval = SeekStream(&obj_stream_clone, 0x0, 0, &NewPosition);
+ mapitest_print_retval(mt, "SeekStream");
+ if (retval != MAPI_E_SUCCESS) {
+ ret = false;
+ }
+ retval = ReadStream(&obj_stream_clone, buf, MT_STREAM_MAX_SIZE, &read_size);
+ mapitest_print_retval_fmt(mt, "ReadStream", "(0x%x bytes read)", read_size);
+ if (retval != MAPI_E_SUCCESS) {
+ ret = false;
+ }
+
+ /* Delete the message */
errno = 0;
id_msgs[0] = mapi_object_get_id(&obj_message);
retval = DeleteMessage(&obj_folder, id_msgs, 1);
@@ -1029,6 +1051,7 @@
}
/* Release */
+ mapi_object_release(&obj_stream_clone);
mapi_object_release(&obj_stream);
mapi_object_release(&obj_attach);
mapi_object_release(&obj_message);
@@ -2270,15 +2293,15 @@
/**
- \details Test the DeletePropertiesNoReplicate (0x7a) operation
+ \details Test the SetPropertiesNoReplicate (0x79) and
+ DeletePropertiesNoReplicate (0x7a) operations
This function:
-# Opens the mailbox
-# Create a test folder
- -# Creates a reference email, and sets some properties on it
- -# Delete properties from this message
- -# Checks that properties got deleted
- -# Deletes both email and the test folder
+ -# Sets some properties on the test folder
+ -# Delete properties from the test folder
+ -# Deletes the test folder
\todo It would be useful to test the problem return values
@@ -2286,73 +2309,66 @@
\return true on success, otherwise false
*/
-_PUBLIC_ bool mapitest_oxcprpt_DeletePropertiesNoReplicate(struct mapitest *mt)
+_PUBLIC_ bool mapitest_oxcprpt_NoReplicate(struct mapitest *mt)
{
enum MAPISTATUS retval;
mapi_object_t obj_store;
mapi_object_t obj_top_folder;
mapi_id_t id_top_folder;
mapi_object_t obj_ref_folder;
- mapi_object_t obj_ref_message;
const char *name = NULL;
- const char *subject = NULL;
+ const char *comment = NULL;
struct SPropValue lpProp[3];
struct SPropTagArray *SPropTagArray;
struct SPropValue *lpProps;
uint32_t cValues;
- bool result;
+ bool ret = true;
/* Step 1. Logon Private Mailbox */
mapi_object_init(&obj_store);
retval = OpenMsgStore(mt->session, &obj_store);
mapitest_print_retval_step_fmt(mt, "1.", "OpenMsgStore", "(%s)", "Logon Private Mailbox");
if (retval != MAPI_E_SUCCESS) {
- return false;
+ ret = false;
+ goto cleanup;
}
mapi_object_init(&obj_top_folder);
retval = GetDefaultFolder(&obj_store, &id_top_folder, olFolderTopInformationStore);
if (retval != MAPI_E_SUCCESS) {
- return false;
+ ret = false;
+ goto cleanup;
}
retval = OpenFolder(&obj_store, id_top_folder, &obj_top_folder);
if (retval != MAPI_E_SUCCESS) {
- return false;
+ ret = false;
+ goto cleanup;
}
- /* Step 2: Create reference folder */
+ /* Step 2: Create test folder */
mapi_object_init(&obj_ref_folder);
retval = CreateFolder(&obj_top_folder, FOLDER_GENERIC, MT_DIRNAME_TOP, NULL,
OPEN_IF_EXISTS, &obj_ref_folder);
mapitest_print_retval_step_fmt(mt, "2.", "CreateFolder", "(%s)", "Create the test folder");
if (retval != MAPI_E_SUCCESS) {
- return false;
+ ret = false;
+ goto cleanup;
}
- /* Step 3: Create reference message */
- mapi_object_init(&obj_ref_message);
- result = mapitest_common_message_create(mt, &obj_ref_folder, &obj_ref_message, MT_MAIL_SUBJECT);
- mapitest_print_retval_step_fmt(mt, "3.1.", "mapitest_common_message_create", "(%s)", "Create a reference email");
- if (!result) {
- return false;
- }
- retval = SaveChangesMessage(&obj_ref_folder, &obj_ref_message, KeepOpenReadWrite);
- if (retval != MAPI_E_SUCCESS) {
- return false;
- }
-
- name = talloc_asprintf(mt->mem_ctx, "Reference: %s", "display name");
- subject = talloc_asprintf(mt->mem_ctx, "Reference: %s", "subject");
+ /* Step 3: Set properties on the test folder */
+ name = talloc_asprintf(mt->mem_ctx, "Reference: %s", "new name");
+ comment = talloc_asprintf(mt->mem_ctx, "Reference: %s", "the folder comment");
set_SPropValue_proptag(&lpProp[0], PR_DISPLAY_NAME, (const void *)name);
- set_SPropValue_proptag(&lpProp[1], PR_CONVERSATION_TOPIC, (const void *)subject);
- retval = SetProps(&obj_ref_message, lpProp, 2);
- mapitest_print_retval_step_fmt(mt, "3.2.", "SetProps", "(%s)", "Set email properties");
+ set_SPropValue_proptag(&lpProp[1], PR_COMMENT, (const void *)comment);
+ retval = SetPropertiesNoReplicate(&obj_ref_folder, lpProp, 2);
+ mapitest_print_retval_step_fmt(mt, "3.", "SetProps", "(%s)", "Set folder properties");
if (retval != MAPI_E_SUCCESS) {
- return false;
+ ret = false;
+ goto cleanup;
}
/* Step 4: Double check with GetProps */
- SPropTagArray = set_SPropTagArray(mt->mem_ctx, 0x2, PR_DISPLAY_NAME, PR_CONVERSATION_TOPIC);
- retval = GetProps(&obj_ref_message, SPropTagArray, &lpProps, &cValues);
+ SPropTagArray = set_SPropTagArray(mt->mem_ctx, 0x2, PR_DISPLAY_NAME, PR_COMMENT);
+ retval = GetProps(&obj_ref_folder, SPropTagArray, &lpProps, &cValues);
MAPIFreeBuffer(SPropTagArray);
if (lpProps[0].value.lpszA) {
if (!strncmp(name, lpProps[0].value.lpszA, strlen(lpProps[0].value.lpszA))) {
@@ -2361,45 +2377,235 @@
} else {
mapitest_print(mt, "* Step 4.1. - Check: Reference props set [FAILURE] (%s)\n",
lpProps[0].value.lpszA);
+ ret = false;
+ goto cleanup;
}
}
if (lpProps[1].value.lpszA) {
- if (!strncmp(subject, lpProps[1].value.lpszA, strlen(lpProps[1].value.lpszA))) {
+ if (!strncmp(comment, lpProps[1].value.lpszA, strlen(lpProps[1].value.lpszA))) {
mapitest_print(mt, "* Step 4.2. - Check: Reference props set - [SUCCESS] (%s)\n",
lpProps[1].value.lpszA);
} else {
mapitest_print(mt, "* Step 4.2. - Check: Reference props set [FAILURE] (%s)\n",
lpProps[1].value.lpszA);
+ ret = false;
+ goto cleanup;
}
}
/* Step 5. Delete Properties */
- SPropTagArray = set_SPropTagArray(mt->mem_ctx, 0x1, PR_CONVERSATION_TOPIC);
- retval = DeletePropertiesNoReplicate(&obj_ref_message, SPropTagArray);
+ SPropTagArray = set_SPropTagArray(mt->mem_ctx, 0x1, PR_COMMENT);
+ retval = DeletePropertiesNoReplicate(&obj_ref_folder, SPropTagArray);
MAPIFreeBuffer(SPropTagArray);
- mapitest_print_retval_step_fmt(mt, "5.", "DeletePropertiesNoReplicate", "PR_CONVERSATION_TOPIC");
+ mapitest_print_retval_step_fmt(mt, "5.", "DeletePropertiesNoReplicate", "PR_COMMENT");
/* Step 6. Double check with GetProps */
- SPropTagArray = set_SPropTagArray(mt->mem_ctx, 0x1, PR_CONVERSATION_TOPIC);
- retval = GetProps(&obj_ref_message, SPropTagArray, &lpProps, &cValues);
+ SPropTagArray = set_SPropTagArray(mt->mem_ctx, 0x1, PR_COMMENT);
+ retval = GetProps(&obj_ref_folder, SPropTagArray, &lpProps, &cValues);
MAPIFreeBuffer(SPropTagArray);
- if (get_SPropValue(lpProps, PR_CONVERSATION_TOPIC) == NULL) {
- mapitest_print(mt, "* Step 5.1. - GetProps verifier [SUCCESS]\n");
+ if (get_SPropValue(lpProps, PR_COMMENT) == NULL) {
+ mapitest_print(mt, "* Step 6.1. - GetProps verifier [SUCCESS]\n");
} else {
- mapitest_print(mt, "* Step 5.1. - GetProps verifier [FAILURE]:\n");
+ mapitest_print(mt, "* Step 6.1. - GetProps verifier [FAILURE]:\n");
}
- /* Step 7: cleanup folders */
+ /* Cleanup and release */
+cleanup:
retval = DeleteFolder(&obj_top_folder, mapi_object_get_id(&obj_ref_folder),
DEL_FOLDERS | DEL_MESSAGES | DELETE_HARD_DELETE, NULL);
- mapitest_print_retval_step(mt, "6.", "DeleteFolder");
-
- /* Release */
- mapi_object_release(&obj_ref_message);
+ mapitest_print_retval_step(mt, "7.", "DeleteFolder");
mapi_object_release(&obj_ref_folder);
mapi_object_release(&obj_top_folder);
mapi_object_release(&obj_store);
+ return ret;
+}
- return true;
+/**
+ \details Test WriteAndCommitStream (0x90) operation.
+
+ This function:
+ -# Logs in
+ -# Opens the Outbox folder
+ -# Creates a test message
+ -# Creates an attachment on the test messages and set properties on the attachment
+ -# Opens a stream on the attachment
+ -# Sets the stream size
+ -# Write and commits into the stream
+ -# Saves the message
+ -# Gets stream size and compare values
+ -# Opens the stream again with different permissions
+ -# Reads the stream and compares buffers
+ -# Deletes the test message
+
+ \param mt pointer to the top-level mapitest structure
+
+ \return true on success, otherwise -1
+ */
+_PUBLIC_ bool mapitest_oxcprpt_WriteAndCommitStream(struct mapitest *mt)
+{
+ enum MAPISTATUS retval;
+ bool ret = true;
+ mapi_object_t obj_store;
+ mapi_object_t obj_folder;
+ mapi_object_t obj_message;
+ mapi_object_t obj_attach;
+ mapi_object_t obj_stream;
+ mapi_id_t id_folder;
+ DATA_BLOB data;
+ struct SPropValue attach[3];
+ char *stream = NULL;
+ char *out_stream = NULL;
+ const uint32_t stream_len = 0x1000;
+ unsigned char buf[0x1000];
+ uint32_t StreamSize = 0;
+ uint16_t read_size = 0;
+ uint16_t write_len = 0;
+ uint32_t offset = 0;
+
+
+ stream = mapitest_common_genblob(mt->mem_ctx, stream_len);
+ if (stream == NULL) {
+ return false;
+ }
+
+ /* Step 1. Logon */
+ mapi_object_init(&obj_store);
+ retval = OpenMsgStore(mt->session, &obj_store);
+ mapitest_print_retval(mt, "OpenMsgStore");
+ if (retval != MAPI_E_SUCCESS) {
+ return false;
+ }
+
+ /* Step 2. Open Inbox folder */
+ retval = GetDefaultFolder(&obj_store, &id_folder, olFolderInbox);
+ mapitest_print_retval(mt, "GetDefaultFolder");
+ if (retval != MAPI_E_SUCCESS) {
+ return false;
+ }
+
+ mapi_object_init(&obj_folder);
+ retval = OpenFolder(&obj_store, id_folder, &obj_folder);
+ mapitest_print_retval(mt, "OpenFolder");
+ if (retval != MAPI_E_SUCCESS) {
+ return false;
+ }
+
+ /* Step 3. Create the message */
+ mapi_object_init(&obj_message);
+ mapitest_common_message_create(mt, &obj_folder, &obj_message, MT_MAIL_SUBJECT);
+
+ /* Step 4. Create the attachment */
+ mapi_object_init(&obj_attach);
+ retval = CreateAttach(&obj_message, &obj_attach);
+ mapitest_print_retval(mt, "CreateAttach");
+ if (retval != MAPI_E_SUCCESS) {
+ ret = false;
+ }
+
+ attach[0].ulPropTag = PR_ATTACH_METHOD;
+ attach[0].value.l = ATTACH_BY_VALUE;
+ attach[1].ulPropTag = PR_RENDERING_POSITION;
+ attach[1].value.l = 0;
+ attach[2].ulPropTag = PR_ATTACH_FILENAME;
+ attach[2].value.lpszA = MT_MAIL_ATTACH;
+
+ retval = SetProps(&obj_attach, attach, 3);
+ if (retval != MAPI_E_SUCCESS) {
+ ret = false;
+ }
+
+ /* Step 5. Open the stream */
+ mapi_object_init(&obj_stream);
+ retval = OpenStream(&obj_attach, PR_ATTACH_DATA_BIN, 2, &obj_stream);
+ mapitest_print_retval(mt, "OpenStream");
+ if (retval != MAPI_E_SUCCESS) {
+ ret = false;
+ }
+
+ /* Step 6. Set the stream size */
+ retval = SetStreamSize(&obj_stream, (uint64_t) stream_len);
+ mapitest_print_retval(mt, "SetStreamSize");
+ if (retval != MAPI_E_SUCCESS) {
+ ret = false;
+ }
+
+ /* Step 7. Write the stream */
+ write_len = 0;
+
+ data.length = stream_len;
+ data.data = (uint8_t *) stream;
+ retval = WriteAndCommitStream(&obj_stream, &data, &write_len);
+ mapitest_print_retval_fmt(mt, "WriteStream", "(0x%x bytes written)", write_len);
+ if (retval != MAPI_E_SUCCESS) {
+ ret = false;
+ }
+
+ /* Step 8. Save the attachment */
+ retval = SaveChangesAttachment(&obj_message, &obj_attach, KeepOpenReadOnly);
+ mapitest_print_retval(mt, "SaveChangesAttachment");
+ if (retval != MAPI_E_SUCCESS) {
+ ret = false;
+ }
+
+ retval = SaveChangesMessage(&obj_folder, &obj_message, KeepOpenReadOnly);
+ mapitest_print_retval(mt, "SaveChangesMessage");
+ if (retval != MAPI_E_SUCCESS) {
+ ret = false;
+ }
+
+ /* Step 9. Get stream size */
+ retval = GetStreamSize(&obj_stream, &StreamSize);
+ mapitest_print_retval(mt, "GetStreamSize");
+ if (retval != MAPI_E_SUCCESS) {
+ ret = false;
+ }
+ mapitest_print(mt, "* %-35s: %s\n", "StreamSize comparison",
+ (StreamSize == stream_len) ? "[PASSED]" : "[FAILURE]");
+
+ /* Step 10. Read the stream */
+ mapi_object_release(&obj_stream);
+ mapi_object_init(&obj_stream);
+
+ retval = OpenStream(&obj_attach, PR_ATTACH_DATA_BIN, 0, &obj_stream);
+ mapitest_print_retval(mt, "OpenStream");
+ if (retval != MAPI_E_SUCCESS) {
+ ret = false;
+ }
+
+ offset = 0;
+ out_stream = talloc_size(mt->mem_ctx, StreamSize + 1);
+ do {
+ retval = ReadStream(&obj_stream, buf, MT_STREAM_MAX_SIZE, &read_size);
+ mapitest_print_retval_fmt(mt, "ReadStream", "(0x%x bytes read)", read_size);
+ memcpy(out_stream + offset, buf, read_size);
+ offset += read_size;
+ if (retval != MAPI_E_SUCCESS) {
+ ret = false;
+ break;
+ }
+ } while (read_size && (offset != StreamSize));
+ out_stream[offset] = '\0';
+
+ if (offset) {
+ if (!strcmp(stream, out_stream)) {
+ mapitest_print(mt, "* %-35s: [IN,OUT] stream [PASSED]\n", "Comparison");
+ } else {
+ mapitest_print(mt, "* %-35s: [IN,OUT] stream [FAILURE]\n", "Comparison");
+
+ }
+ }
+
+ /* Release */
+ mapi_object_release(&obj_stream);
+ mapi_object_release(&obj_attach);
+ mapi_object_release(&obj_message);
+ mapi_object_release(&obj_folder);
+ mapi_object_release(&obj_store);
+
+ talloc_free(stream);
+ talloc_free(out_stream);
+
+ return ret;
}
+
Modified: trunk/openchange/utils/mapitest/modules/module_oxomsg.c
===================================================================
--- trunk/openchange/utils/mapitest/modules/module_oxomsg.c 2009-04-30 18:06:45 UTC (rev 2733)
+++ trunk/openchange/utils/mapitest/modules/module_oxomsg.c 2009-04-30 18:06:50 UTC (rev 2734)
@@ -470,7 +470,53 @@
return ret;
}
+/**
+ \details Test the TransportNewMail (0x51) operation
+ This function:
+ -# Logs on to the user private mailbox
+ -# Create a filled test folder, and open it.
+ -# Perform the TransportNewMail operation
+ -# Clean up test environment
+
+ \param mt pointer on the top-level mapitest structure
+
+ \return true on success, otherwise false
+ */
+_PUBLIC_ bool mapitest_oxomsg_TransportNewMail(struct mapitest *mt)
+{
+ enum MAPISTATUS retval;
+ mapi_object_t obj_htable;
+ bool ret = true;
+ struct mt_common_tf_ctx *context;
+ int i;
+
+
+
+ /* Logon and create filled test folder*/
+ if (! mapitest_common_setup(mt, &obj_htable, NULL)) {
+ return false;
+ }
+
+ context = mt->priv;
+
+ /* Perform the TransportNewMail operation */
+ for (i = 0; i<10; ++i) {
+ retval = TransportNewMail(&(context->obj_test_folder), &(context->obj_test_msg[i]), "IPM.Note", MSGFLAG_SUBMIT);
+ mapitest_print_retval(mt, "TransportNewMail");
+ if (retval != MAPI_E_SUCCESS) {
+ ret = false;
+ }
+ }
+
+ /* Clean up */
+ mapi_object_release(&obj_htable);
+ mapitest_common_cleanup(mt);
+
+ return ret;
+}
+
+
/**
\details Test the GetTransportFolder (0x6d) operation
Modified: trunk/openchange/utils/openchangeclient.c
===================================================================
--- trunk/openchange/utils/openchangeclient.c 2009-04-30 18:06:45 UTC (rev 2733)
+++ trunk/openchange/utils/openchangeclient.c 2009-04-30 18:06:50 UTC (rev 2734)
@@ -363,9 +363,7 @@
} while (read_size);
close(fd);
-
mapi_object_release(&obj_stream);
- close(fd);
talloc_free(mem_ctx);
return true;
@@ -1598,7 +1596,7 @@
printf("| ");
}
newname = utf8tolinux(mem_ctx, name);
- printf("|---+ %-15s : %-20s (Total: %u / Unread: %u - Container class: %s) [FID: 0x%.16"PRIx64"]\n",
+ printf("|---+ %-15s : %-20s (Total: %u / Unread: %u - Container class: %s) [FID: 0x%016"PRIx64"]\n",
newname, comment?comment:"", total?*total:0, unread?*unread:0,
get_container_class(mem_ctx, parent, *fid), *fid);
MAPIFreeBuffer(newname);
@@ -1653,7 +1651,7 @@
printf("| ");
}
newname = utf8tolinux(mem_ctx, name);
- printf("|---+ %-15s [FID: 0x.16%"PRIx64"]\n", newname, *fid);
+ printf("|---+ %-15s [FID: 0x%016"PRIx64"]\n", newname, *fid);
MAPIFreeBuffer(newname);
if (*child) {
ret = get_child_folders_pf(mem_ctx, &obj_folder, *fid, count + 1);
@@ -2316,8 +2314,10 @@
ulEventMask = fnevNewMail|fnevObjectCreated|fnevObjectDeleted|
fnevObjectModified|fnevObjectMoved|fnevObjectCopied|
fnevSearchComplete|fnevTableModified|fnevStatusObjectModified;
- retval = Subscribe(obj_store, &ulConnection, ulEventMask, true, (mapi_notify_callback_t)callback);
- retval = Subscribe(&obj_inbox, &ulConnection, ulEventMask, false, (mapi_notify_callback_t)callback);
+ retval = Subscribe(obj_store, &ulConnection, ulEventMask, true, (mapi_notify_callback_t)callback,
+ (void*) obj_store);
+ retval = Subscribe(&obj_inbox, &ulConnection, ulEventMask, false, (mapi_notify_callback_t)callback,
+ (void*) obj_store);
if (retval != MAPI_E_SUCCESS) return false;
/* wait for notifications: infinite loop */
More information about the Pkg-samba-maint
mailing list