public static RopResult GetPropertiesSpecific(int serverId, int handleIndex, Sequence<string> propertyTag) { // The contraction conditions Condition.IsTrue(connections.Count > 0); Condition.IsTrue(connections.Keys.Contains(serverId)); // Initialize the return value. RopResult result = RopResult.InvalidParameter; // Identify whether the Current message is existent or not. ConnectionData changeConnection = connections[serverId]; if (connections[serverId].FolderContainer.Count > 0) { result = RopResult.Success; } else if (connections[serverId].MessageContainer.Count > 0) { AbstractMessage currentMessage = new AbstractMessage(); bool ismessageExist = false; int messageIndex = 0; foreach (AbstractMessage tempMesage in changeConnection.MessageContainer) { if (tempMesage.MessageHandleIndex == handleIndex) { ismessageExist = true; currentMessage = tempMesage; messageIndex = changeConnection.MessageContainer.IndexOf(tempMesage); } } if (ismessageExist) { // Set value for MessageProperties currentMessage.MessageProperties = propertyTag; changeConnection.MessageContainer = changeConnection.MessageContainer.Update(messageIndex, currentMessage); connections[serverId] = changeConnection; result = RopResult.Success; } } return result; }
public static RopResult SetProperties(int serverId, int handleIndex, Sequence<string> propertyTag) { // The construction conditions Condition.IsTrue(connections.Count > 0); Condition.IsTrue(connections.Keys.Contains(serverId)); Condition.IsTrue(connections[serverId].MessageContainer.Count > 0); // Initialize the return value. RopResult result = RopResult.InvalidParameter; // Get value of current ConnectionData ConnectionData changeConnection = connections[serverId]; // Identify whether the Current message is existent or not. AbstractMessage currentMessage = new AbstractMessage(); bool ismessageExist = false; int messageIndex = 0; // Find current message. foreach (AbstractMessage tempMesage in changeConnection.MessageContainer) { if (tempMesage.MessageHandleIndex == handleIndex) { ismessageExist = true; currentMessage = tempMesage; messageIndex = changeConnection.MessageContainer.IndexOf(tempMesage); } } if (ismessageExist) { foreach (string propertyName in propertyTag) { // Identify whether the property is existent or not in MessageProperties. if (!currentMessage.MessageProperties.Contains(propertyName)) { // Add property to MessageProperties. currentMessage.MessageProperties = currentMessage.MessageProperties.Add(propertyName); } } changeConnection.MessageContainer = changeConnection.MessageContainer.Update(messageIndex, currentMessage); connections[serverId] = changeConnection; result = RopResult.Success; } return result; }
public static RopResult CreateAttachment(int serverId, int messageHandleIndex, out int attachmentHandleIndex) { // The contractions conditions. Condition.IsTrue(connections.Count > 0); Condition.IsTrue(connections.Keys.Contains(serverId)); // Initialize the return value. RopResult result = RopResult.InvalidParameter; attachmentHandleIndex = -1; // Identify whether the Current message is existent or not. ConnectionData changeConnection = connections[serverId]; AbstractMessage currentMessage = new AbstractMessage(); bool iscurrentMessageExist = false; int currentMessageIndex = 0; // Find current message foreach (AbstractMessage tempMessage in changeConnection.MessageContainer) { if (tempMessage.MessageHandleIndex == messageHandleIndex) { iscurrentMessageExist = true; currentMessage = tempMessage; currentMessageIndex = changeConnection.MessageContainer.IndexOf(tempMessage); } } if (iscurrentMessageExist) { // Create a new attachment. AbstractAttachment currentAttachment = new AbstractAttachment(); // Set value for new attachment. currentMessage.AttachmentCount++; changeConnection.MessageContainer.Update(currentMessageIndex, currentMessage); currentAttachment.AttachmentHandleIndex = AdapterHelper.GetHandleIndex(); attachmentHandleIndex = currentAttachment.AttachmentHandleIndex; // Add new attachment to attachment container. changeConnection.AttachmentContainer = changeConnection.AttachmentContainer.Add(currentAttachment); connections[serverId] = changeConnection; result = RopResult.Success; } // There is no negative behavior specified in this protocol, so this operation always return true. return result; }
public static RopResult SaveChangesMessage(int serverId, int messageHandleIndex, out int messageIdIndex) { // The contraction conditions. Condition.IsTrue(connections.Count > 0); Condition.IsTrue(connections.Keys.Contains(serverId)); Condition.IsTrue(connections[serverId].MessageContainer.Count > 0); // Initialize the return value. RopResult result = RopResult.InvalidParameter; messageIdIndex = -1; // Identify whether the Current message is existent or not. ConnectionData changeConnection = connections[serverId]; AbstractMessage currentMessage = new AbstractMessage(); bool isMessageExist = false; int messageIndex = 0; // Find current message foreach (AbstractMessage tempMesage in changeConnection.MessageContainer) { if (tempMesage.MessageHandleIndex == messageHandleIndex) { isMessageExist = true; currentMessage = tempMesage; messageIndex = changeConnection.MessageContainer.IndexOf(tempMesage); } } if (isMessageExist) { // Find the parent folder of relate message AbstractFolder parentfolder = new AbstractFolder(); int parentfolderIndex = 0; foreach (AbstractFolder tempFolder in changeConnection.FolderContainer) { if (tempFolder.FolderHandleIndex == currentMessage.FolderHandleIndex) { parentfolder = tempFolder; parentfolderIndex = changeConnection.FolderContainer.IndexOf(tempFolder); } } // If new message then return a new message id. if (currentMessage.MessageIdIndex == 0) { currentMessage.MessageIdIndex = AdapterHelper.GetObjectIdIndex(); // Because if Create a new messageID then the action which convert GID to a short-term internal identifier and assign it to an imported object execute in MS_OXCFXICSAdapter. So cover this requirement here. ModelHelper.CaptureRequirement(1910, "[In Identifying Objects and Maintaining Change Numbers] Convert the GID structure ([MS-OXCDATA] section 2.2.1.3) to a short-term internal identifier and assign it to an imported object, if the external identifier is a GID value."); } // Set value for the current Message messageIdIndex = currentMessage.MessageIdIndex; parentfolder.MessageIds = parentfolder.MessageIds.Add(messageIdIndex); changeConnection.FolderContainer = changeConnection.FolderContainer.Update(parentfolderIndex, parentfolder); // Assign a new Change number. currentMessage.ChangeNumberIndex = ModelHelper.GetChangeNumberIndex(); // Because of executed import operation before execute RopSaveChangesMessage operation. And assign a new changeNumber. So can cover this requirement here. ModelHelper.CaptureRequirement( 1906, @"[In Identifying Objects and Maintaining Change Numbers]Upon successful import of a new or changed object using ICS upload, the server MUST do the following when receiving the RopSaveChangesMessage ROP:Assign the object a new internal change number (PidTagChangeNumber property (section 2.2.1.2.3))."); // Because of it must execute RopSaveChangesMessage operation after the messaging object each time and assign a new changeNumber. So can cover this requirement Spec here. ModelHelper.CaptureRequirement(1898, "[In Identifying Objects and Maintaining Change Numbers]A new change number is assigned to a messaging object each time it is modified."); currentMessage.ReadStateChangeNumberIndex = 0; // Update current Message into MessageContainer changeConnection.MessageContainer = changeConnection.MessageContainer.Update(messageIndex, currentMessage); connections[serverId] = changeConnection; if (priorOperation == MS_OXCFXICS.PriorOperation.RopCreateMessage && messageIndex > 0) { // When the prior operate is create message and in this ROP return a valid messageIDIndex means this requirement verified. ModelHelper.CaptureRequirement( 1890001, @"[In Identifying Objects and Maintaining Change Numbers] On creation, objects in the mailbox are assigned internal identifiers, commonly known as Message ID structures ([MS-OXCDATA] section 2.2.1.2) for messages."); } result = RopResult.Success; } return result; }
public static RopResult CreateMessage(int serverId, int folderHandleIndex, int folderIdIndex, bool associatedFlag, out int messageHandleIndex) { // The contractions conditions. Condition.IsTrue(connections.Count > 0); Condition.IsTrue(connections.Keys.Contains(serverId)); Condition.IsTrue(connections[serverId].LogonHandleIndex > 0); // Initialize the return value. RopResult result = RopResult.InvalidParameter; messageHandleIndex = -1; // Identify whether the Current Folder is existent or not. ConnectionData changeConnection = connections[serverId]; AbstractFolder parentfolder = new AbstractFolder(); bool isParentFolderExist = false; int parentfolderIndex = 0; // Find current folder. foreach (AbstractFolder tempfolder in changeConnection.FolderContainer) { if (tempfolder.FolderHandleIndex == folderHandleIndex) { isParentFolderExist = true; parentfolder = tempfolder; parentfolderIndex = changeConnection.FolderContainer.IndexOf(tempfolder); } } if (isParentFolderExist) { // Create a new message object. AbstractMessage currentMessage = new AbstractMessage { IsFAImessage = associatedFlag, IsRead = true, FolderHandleIndex = folderHandleIndex, FolderIdIndex = folderIdIndex, MessageHandleIndex = AdapterHelper.GetHandleIndex(), MessageProperties = new Sequence<string>() }; // Set value for new message. // Initialize message properties. messageHandleIndex = currentMessage.MessageHandleIndex; // Update folder changeConnection.FolderContainer = changeConnection.FolderContainer.Update(parentfolderIndex, parentfolder); // Add new message to MessageContainer. changeConnection.MessageContainer = changeConnection.MessageContainer.Add(currentMessage); connections[serverId] = changeConnection; if (currentMessage.MessageHandleIndex > 0) { // Because only if the folder is right can return a valid message handle index, then the requirement is verified. ModelHelper.CaptureRequirement( 1890001, @"[In Identifying Objects and Maintaining Change Numbers] On creation, objects in the mailbox are assigned internal identifiers, commonly known as Message ID structures ([MS-OXCDATA] section 2.2.1.2) for messages."); } result = RopResult.Success; } return result; }
public static RopResult OpenMessage(int serverId, int objHandleIndex, int folderIdIndex, int messageIdIndex, out int openMessageHandleIndex) { // The contractions conditions. Condition.IsTrue(connections.Count > 0); Condition.IsTrue(connections.Keys.Contains(serverId)); Condition.IsTrue(connections[serverId].LogonHandleIndex > 0); Condition.IsTrue(connections[serverId].FolderContainer.Count > 0); Condition.IsTrue(connections[serverId].MessageContainer.Count > 0); // Initialize the return value. RopResult result = RopResult.InvalidParameter; openMessageHandleIndex = 0; // Get information of ConnectionData. ConnectionData changeConnection = connections[serverId]; // Identify whether the current message is existent or not. AbstractMessage currentMessage = new AbstractMessage(); bool ismessagExist = false; // Record current message. int messageIndex = 0; foreach (AbstractMessage tempMessage in changeConnection.MessageContainer) { if (tempMessage.MessageIdIndex == messageIdIndex) { ismessagExist = true; currentMessage = tempMessage; messageIndex = changeConnection.MessageContainer.IndexOf(tempMessage); } } if (ismessagExist) { // Set value to current folder. currentMessage.MessageHandleIndex = AdapterHelper.GetHandleIndex(); openMessageHandleIndex = currentMessage.MessageHandleIndex; // Update current message. changeConnection.MessageContainer = changeConnection.MessageContainer.Update(messageIndex, currentMessage); connections[serverId] = changeConnection; result = RopResult.Success; } return result; }
public static RopResult SynchronizationImportMessageMove(int serverId, int synchronizationUploadContextHandleIndex, int sourceFolderIdIndex, int destinationFolderIdIndex, int sourceMessageIdIndex, int sourceFolderHandleIndex, int destinationFolderHandleIndex, bool inewerClientChange, out bool iolderversion, out bool icnpc) { // The contractions conditions. Condition.IsTrue(connections.Count > 0); Condition.IsTrue(connections.Keys.Contains(serverId)); Condition.IsTrue(connections[serverId].FolderContainer.Count > 1); // Initialize the return value. RopResult result = RopResult.InvalidParameter; iolderversion = false; icnpc = false; // Get the current ConnectionData value. ConnectionData changeConnection = connections[serverId]; // Identify whether Current Upload information is existent or not. bool isCurrentUploadinfoExist = false; // Record the current Upload information. int currentUploadIndex = 0; AbstractUploadInfo uploadInfo = new AbstractUploadInfo(); foreach (AbstractUploadInfo tempUploadInfo in changeConnection.UploadContextContainer) { if (tempUploadInfo.UploadHandleIndex == synchronizationUploadContextHandleIndex) { // Set the value for current upload information when current upload Information is existent. isCurrentUploadinfoExist = true; uploadInfo = tempUploadInfo; currentUploadIndex = changeConnection.UploadContextContainer.IndexOf(tempUploadInfo); } } // Create variable of relate to source Folder. AbstractFolder sourceFolder = new AbstractFolder(); bool isSourceFolderExist = false; int sourceFolderIndex = 0; // Create variable of relate to destination Folder. AbstractFolder destinationFolder = new AbstractFolder(); bool isdestinationFolderExist = false; int destinationFolderIndex = 0; // Create a new message. AbstractMessage movedMessage = new AbstractMessage(); // Identify whether the Moved Message is existent or not. bool isMovedMessageExist = false; int movedMessageIndex = 0; foreach (AbstractFolder tempFolder in changeConnection.FolderContainer) { if (tempFolder.FolderIdIndex == sourceFolderIdIndex && tempFolder.FolderHandleIndex == sourceFolderHandleIndex) { // Set the value to the variable when the source folder is existent. isSourceFolderExist = true; sourceFolder = tempFolder; sourceFolderIndex = changeConnection.FolderContainer.IndexOf(tempFolder); } } foreach (AbstractFolder tempFolder in changeConnection.FolderContainer) { if (tempFolder.FolderIdIndex == destinationFolderIdIndex && tempFolder.FolderHandleIndex == destinationFolderHandleIndex) { // Set the value to the related variable when the destination folder is existent. isdestinationFolderExist = true; destinationFolder = tempFolder; destinationFolderIndex = changeConnection.FolderContainer.IndexOf(tempFolder); } } foreach (AbstractMessage tempMessage in changeConnection.MessageContainer) { if (tempMessage.MessageIdIndex == sourceMessageIdIndex) { // Set the value to the related variable when the source Message is existent. isMovedMessageExist = true; movedMessage = tempMessage; movedMessageIndex = changeConnection.MessageContainer.IndexOf(tempMessage); } } if (isSourceFolderExist && isdestinationFolderExist && isMovedMessageExist && isCurrentUploadinfoExist) { // Set value for the new abstract message property. movedMessage.FolderIdIndex = destinationFolder.FolderIdIndex; movedMessage.FolderHandleIndex = destinationFolder.FolderHandleIndex; // Assigned a new change. movedMessage.ChangeNumberIndex = ModelHelper.GetChangeNumberIndex(); // Assigned a new message id. movedMessage.MessageIdIndex = AdapterHelper.GetObjectIdIndex(); // Update message Container. changeConnection.MessageContainer = changeConnection.MessageContainer.Update(movedMessageIndex, movedMessage); // Remove the current message id from MessageIds of source folder. sourceFolder.MessageIds = sourceFolder.MessageIds.Remove(movedMessage.MessageIdIndex); changeConnection.FolderContainer = changeConnection.FolderContainer.Update(sourceFolderIndex, sourceFolder); // Remove the current message id from MessageIds of destination Folder. destinationFolder.MessageIds = destinationFolder.MessageIds.Add(movedMessage.MessageIdIndex); changeConnection.FolderContainer = changeConnection.FolderContainer.Update(destinationFolderIndex, destinationFolder); // Add information of Upload context uploadInfo.IsnewerClientChange = inewerClientChange; uploadInfo.RelatedFastTransferOperation = EnumFastTransferOperation.SynchronizationImportMessageMove; // Update the upload context container changeConnection.UploadContextContainer = changeConnection.UploadContextContainer.Update(currentUploadIndex, uploadInfo); connections[serverId] = changeConnection; // Identify whether the IsnewerClientChange is true or false. if (uploadInfo.IsnewerClientChange == false) { result = RopResult.Success; ModelHelper.CaptureRequirement( 2449, @"[In Uploading Changes Using ICS] Value is Success indicates No error occurred, or a conflict has been resolved."); // Because if the result is success means the information about moving a message between two existing folders within the same mailbox imported ModelHelper.CaptureRequirement( 839, @"[In RopSynchronizationImportMessageMove ROP] The RopSynchronizationImportMessageMove ROP ([MS-OXCROPS] section 2.2.13.6) imports information about moving a message between two existing folders within the same mailbox."); } else { // Set out put parameter value iolderversion = true; ModelHelper.CaptureRequirement( 875, @"[In RopSynchronizationImportMessageMove ROP Response Buffer] [ Return value (4 bytes):] The following table[In section 2.2.3.2.4.4] contains additional return values[NewerClientChange] , if the ROP succeeded, but the server replica had an older version of a message than the local replica, the return value is 0x00040821."); icnpc = true; ModelHelper.CaptureRequirement( 876, @"[In RopSynchronizationImportMessageMove ROP Response Buffer] [ Return value (4 bytes):] The following table[In section 2.2.3.2.4.4] contains additional return values[NewerClientChange] , if the values of the ChangeNumber and PredecessorChangeList fields, specified in section 2.2.3.2.4.4.1, were not applied to the destination message, the return value is 0x00040821."); ModelHelper.CaptureRequirement( 1892, "[In Identifying Objects and Maintaining Change Numbers]Copying of messaging objects within a mailbox or moving messages between folders of the same mailbox translates into creation of new messaging objects and therefore, new internal identifiers MUST be assigned to new copies."); result = RopResult.NewerClientChange; } // Record RopSynchronizationImportMessageMove operation. priorUploadOperation = PriorOperation.RopSynchronizationImportMessageMove; } return result; }
public static RopResult SynchronizationImportReadStateChanges(int serverId, int uploadContextHandleIndex, int messageHandleIndex, bool ireadstatus) { // The contractions conditions. Condition.IsTrue(connections.Count > 0); Condition.IsTrue(connections.Keys.Contains(serverId)); Condition.IsTrue(connections[serverId].MessageContainer.Count > 0); // Initialize the return value. RopResult result = RopResult.InvalidParameter; ConnectionData changeConnection = connections[serverId]; AbstractMessage currentMessage = new AbstractMessage(); AbstractUploadInfo uploadInfo = new AbstractUploadInfo(); // Identify whether the Message is existent or not and record the index. bool isCurrentMessageExist = false; int currentMessageindex = 0; // Identify whether the Upload information is existent or not and record the index. bool isCurrentUploadinfoExist = false; int currentUploadIndex = 0; foreach (AbstractUploadInfo tempUploadInfo in changeConnection.UploadContextContainer) { if (tempUploadInfo.UploadHandleIndex == uploadContextHandleIndex) { // Set the value to the variable when the upload context is existent. isCurrentUploadinfoExist = true; uploadInfo = tempUploadInfo; currentUploadIndex = changeConnection.UploadContextContainer.IndexOf(tempUploadInfo); } } foreach (AbstractMessage tempMessage in changeConnection.MessageContainer) { if (tempMessage.MessageHandleIndex == messageHandleIndex) { // Set the value to the variable when the Message is existent. isCurrentMessageExist = true; currentMessage = tempMessage; currentMessageindex = changeConnection.MessageContainer.IndexOf(tempMessage); } } if (isCurrentMessageExist) { // Find the parent folder of current message AbstractFolder parentfolder = new AbstractFolder(); int parentfolderIndex = 0; foreach (AbstractFolder tempFolder in changeConnection.FolderContainer) { if (tempFolder.FolderHandleIndex == currentMessage.FolderHandleIndex) { parentfolder = tempFolder; parentfolderIndex = changeConnection.FolderContainer.IndexOf(tempFolder); if (parentfolder.FolderPermission == PermissionLevels.None) { return result = RopResult.AccessDenied; } } } } if (isCurrentUploadinfoExist && isCurrentMessageExist) { // Set the message read status value. if (currentMessage.IsRead != ireadstatus) { currentMessage.IsRead = ireadstatus; // Get read State changeNumber. currentMessage.ReadStateChangeNumberIndex = ModelHelper.GetChangeNumberIndex(); ModelHelper.CaptureRequirement( 2260, @"[In Receiving a RopSynchronizationImportReadStateChanges Request]Upon successful completion of this ROP, the ICS state on the synchronization context MUST be updated by adding the new change number to the MetaTagCnsetRead property (section 2.2.1.1.4)."); } // Record the related Synchronization Operation. uploadInfo.RelatedFastTransferOperation = EnumFastTransferOperation.SynchronizationReadStateChanges; // Update the upload context container and message container. changeConnection.UploadContextContainer = changeConnection.UploadContextContainer.Update(currentUploadIndex, uploadInfo); changeConnection.MessageContainer = changeConnection.MessageContainer.Update(currentMessageindex, currentMessage); connections[serverId] = changeConnection; result = RopResult.Success; ModelHelper.CaptureRequirement( 2449, @"[In Uploading Changes Using ICS] Value is Success indicates No error occurred, or a conflict has been resolved."); // Because if the result is success means message read state changes is imported into the server replica. ModelHelper.CaptureRequirement( 905, @"[In RopSynchronizationImportReadStateChanges ROP] The RopSynchronizationImportReadStateChanges ROP ([MS-OXCROPS] section 2.2.13.3) imports message read state changes into the server replica."); } return result; }
public static RopResult SynchronizationImportMessageChange(int serverId, int uploadContextHandleIndex, int messageIdindex, ImportFlag importFlag, out int importMessageHandleIndex) { // The contractions conditions. Condition.IsTrue(connections.Count > 0); Condition.IsTrue(connections.Keys.Contains(serverId)); Condition.IsTrue(connections[serverId].UploadContextContainer.Count > 0 && connections[serverId].LogonHandleIndex > 0); // Initialize the return value. RopResult result = RopResult.InvalidParameter; importMessageHandleIndex = -1; if ((importFlag & ImportFlag.InvalidParameter) == ImportFlag.InvalidParameter && requirementContainer.ContainsKey(3509001) && requirementContainer[3509001]) { result = RopResult.InvalidParameter; ModelHelper.CaptureRequirement( 3509001, @"[In Appendix A: Product Behavior] If unknown flags are set, implementation does fail the operation. <40> Section 3.2.5.9.4.2: Exchange 2010, Exchange 2013 and Exchange 2016 fail the ROP [RopSynchronizationImportMessageChange] if unknown bit flags are set."); return result; } else if ((importFlag & ImportFlag.InvalidParameter) == ImportFlag.InvalidParameter && requirementContainer.ContainsKey(350900201) && requirementContainer[350900201]) { result = RopResult.Success; ModelHelper.CaptureRequirement( 350900201, @"[In Appendix A: Product Behavior] If unknown flags are set, implementation does not fail the operation. <41> Section 3.2.5.9.4.2: Exchange 2007 do not fail the ROP [RopSynchronizationImportMessageChange] if unknown bit flags are set."); } // Get ConnectionData value. ConnectionData changeConnection = connections[serverId]; AbstractUploadInfo uploadInfo = new AbstractUploadInfo(); // Identify whether the current Upload information is existent or not. bool isCurrentUploadinfoExist = false; // Record current Upload information. int currentUploadIndex = 0; foreach (AbstractUploadInfo tempUploadInfo in changeConnection.UploadContextContainer) { if (tempUploadInfo.UploadHandleIndex == uploadContextHandleIndex) { // Set the value to the current upload context variable when the current upload context is existent. isCurrentUploadinfoExist = true; uploadInfo = tempUploadInfo; currentUploadIndex = changeConnection.UploadContextContainer.IndexOf(tempUploadInfo); } } if (isCurrentUploadinfoExist) { // Create a new Message AbstractMessage currentMessage = new AbstractMessage(); // Identify whether the current message is existent or not. bool isMessageExist = false; // Record the current Message. int currentMessageIndex = 0; foreach (AbstractMessage tempMessage in changeConnection.MessageContainer) { if (tempMessage.MessageIdIndex == messageIdindex) { // Set the value to the variable when the message is existent. isMessageExist = true; currentMessage = tempMessage; currentMessageIndex = changeConnection.MessageContainer.IndexOf(tempMessage); } } if (isMessageExist) { // Set new change number currentMessage.ChangeNumberIndex = ModelHelper.GetChangeNumberIndex(); ModelHelper.CaptureRequirement(1898, "[In Identifying Objects and Maintaining Change Numbers]A new change number is assigned to a messaging object each time it is modified."); // Update the MessageContainer changeConnection.MessageContainer = changeConnection.MessageContainer.Update(currentMessageIndex, currentMessage); } else { // Set the new message handle currentMessage.MessageHandleIndex = AdapterHelper.GetHandleIndex(); // Set property value of abstract message object currentMessage.FolderHandleIndex = uploadInfo.RelatedObjectHandleIndex; currentMessage.FolderIdIndex = uploadInfo.RelatedObjectIdIndex; currentMessage.MessageProperties = new Sequence<string>(); currentMessage.IsRead = true; if ((importFlag & ImportFlag.Normal) == ImportFlag.Normal) { currentMessage.IsFAImessage = false; } if ((importFlag & ImportFlag.Associated) == ImportFlag.Associated) { currentMessage.IsFAImessage = true; // When the Associated is set and the message being imported is an FAI message this requirement is captured. ModelHelper.CaptureRequirement( 813, @"[In RopSynchronizationImportMessageChange ROP Request Buffer] [ImportFlag,when the name is Associated, the value is 0x10] If this flag is set, the message being imported is an FAI message."); } else { currentMessage.IsFAImessage = false; // When the Associated is not set and the message being imported is a normal message this requirement is captured. ModelHelper.CaptureRequirement( 814, @"[In RopSynchronizationImportMessageChange ROP Request Buffer] [ImportFlag,when the name is Associated, the value is 0x10] If this flag is not set, the message being imported is a normal message."); } // Out the new message handle importMessageHandleIndex = currentMessage.MessageHandleIndex; // Because this is out messageHandle so the OutputServerObject is a Message object. ModelHelper.CaptureRequirement(805, "[In RopSynchronizationImportMessageChange ROP Response Buffer]OutputServerObject: The value of this field MUST be the Message object into which the client will upload the rest of the message changes."); currentMessage.ChangeNumberIndex = ModelHelper.GetChangeNumberIndex(); ModelHelper.CaptureRequirement(1897, "[In Identifying Objects and Maintaining Change Numbers]When a new object is created, it is assigned a change number."); // Add new Message to MessageContainer changeConnection.MessageContainer = changeConnection.MessageContainer.Add(currentMessage); // Record the related FastTransferOperation for Upload Information. uploadInfo.RelatedFastTransferOperation = EnumFastTransferOperation.SynchronizationImportMessageChange; // Update the UploadContextContainer. changeConnection.UploadContextContainer = changeConnection.UploadContextContainer.Update(currentUploadIndex, uploadInfo); connections[serverId] = changeConnection; // Record RopSynchronizationImportMessageChange operation. priorOperation = PriorOperation.RopSynchronizationImportMessageChange; result = RopResult.Success; ModelHelper.CaptureRequirement( 2449, @"[In Uploading Changes Using ICS] Value is Success indicates No error occurred, or a conflict has been resolved."); // Because if the result is success means the messages or changes are imported. ModelHelper.CaptureRequirement( 782, @"[In RopSynchronizationImportMessageChange ROP] The RopSynchronizationImportMessageChange ROP ([MS-OXCROPS] section 2.2.13.2) is used to import new messages or changes to existing messages into the server replica."); } } return result; }