/// <summary> /// Initializes a FastTransfer operation to download content from a given messaging object and its descendant subobjects. /// </summary> /// <param name="serverId">A 32-bit signed integer represent the Identity of server.</param> /// <param name="sourceHandleIndex">Folder or message object handle index. </param> /// <param name="handleType">Type of object handle. </param> /// <param name="level">Variable indicate whether copy the descendant subobjects.</param> /// <param name="copyFlag">Defines parameters of the FastTransfer download operation.</param> /// <param name="option">Defines the parameters of a download operation.</param> /// <param name="propertyTags">The list of properties and subobjects to exclude.</param> /// <param name="copyPropertiesHandleIndex">The properties handle index.</param> /// <returns>Indicate the result of this ROP operation.</returns> public RopResult FastTransferSourceCopyProperties(int serverId, int sourceHandleIndex, InputHandleType handleType, bool level, CopyPropertiesCopyFlags copyFlag, SendOptionAlls option, Sequence<string> propertyTags, out int copyPropertiesHandleIndex) { // Initialize ROP data. RopResult result = RopResult.InvalidParameter; RopFastTransferSourceCopyPropertiesRequest req; copyPropertiesHandleIndex = -1; uint sourceHandle = this.handleContainer[sourceHandleIndex]; // Get stream type. switch (handleType) { case InputHandleType.FolderHandle: this.streamType = FastTransferStreamType.folderContent; break; case InputHandleType.MessageHandle: this.streamType = FastTransferStreamType.MessageContent; break; case InputHandleType.AttachmentHandle: this.streamType = FastTransferStreamType.attachmentContent; break; default: break; } // Initialize input propertyTags. ushort propertyCount = (ushort)propertyTags.Count; PropertyTag[] messageSamplePropertyTags = new PropertyTag[propertyCount]; for (int i = 0; i < propertyCount; i++) { messageSamplePropertyTags[i] = this.propertyTagsDictionary[propertyTags[i]]; } this.previousOperation = EnumFastTransferOperation.FastTransferSourceCopyProperties; this.propertyTags = messageSamplePropertyTags; this.copySubObjects = !level; // Construct ROP request. req.RopId = 0x69; req.LogonId = 0x00; req.InputHandleIndex = 0x00; req.OutputHandleIndex = 0x01; // This value specifies the level at which the copy is occurring, which is specified in [MS-OXCROPS]. req.Level = (byte)(level ? 1 : 0); req.CopyFlags = (byte)copyFlag; req.SendOptions = (byte)option; req.PropertyTagCount = propertyCount; req.PropertyTags = messageSamplePropertyTags; // Send request and get response. RopFastTransferSourceCopyPropertiesResponse response = (RopFastTransferSourceCopyPropertiesResponse)this.Process(serverId, req, sourceHandle); result = (RopResult)response.ReturnValue; if (result == RopResult.Success) { copyPropertiesHandleIndex = AdapterHelper.GetHandleIndex(); this.handleContainer.Add(copyPropertiesHandleIndex, this.responseSOHs[response.OutputHandleIndex]); } // Verify ROP FastTransferSourceCopyProperties this.VerifyRopFastTransferSourceCopyProperties(req, response); return result; }
public static RopResult FastTransferSourceCopyProperties(int serverId, int objHandleIndex, InputHandleType handleType, bool level, CopyPropertiesCopyFlags copyFlag, SendOptionAlls option, Sequence<string> propertyTags, out int downloadContextHandleIndex) { // The contraction conditions Condition.IsTrue(connections.Count > 0); Condition.IsTrue(connections.Keys.Contains(serverId)); // Initialize the return value. RopResult result = RopResult.InvalidParameter; // SendOptionAll value is Invalid parameter if ((option == SendOptionAlls.Invalid && (requirementContainer.ContainsKey(3470) && requirementContainer[3470])) || (copyFlag == CopyPropertiesCopyFlags.Invalid && (requirementContainer.ContainsKey(3466) && requirementContainer[3466]))) { downloadContextHandleIndex = -1; } else if (((copyFlag & CopyPropertiesCopyFlags.Move) == CopyPropertiesCopyFlags.Move) && (requirementContainer.ContainsKey(3466) && requirementContainer[3466])) { // CopyPropertiesCopyFlags value is Move. result = RopResult.NotImplemented; downloadContextHandleIndex = -1; } else { // Create a new download context. AbstractDownloadInfo downloadInfo = new AbstractDownloadInfo(); ConnectionData changeConnection = connections[serverId]; bool isObjExist = false; connections.Remove(serverId); if (handleType == InputHandleType.MessageHandle) { foreach (AbstractMessage temp in changeConnection.MessageContainer) { if (temp.MessageHandleIndex == objHandleIndex) { isObjExist = true; } } Condition.IsTrue(isObjExist); // Set value for new download context. downloadContextHandleIndex = AdapterHelper.GetHandleIndex(); downloadInfo.DownloadHandleIndex = downloadContextHandleIndex; downloadInfo.AbstractFastTransferStreamType = FastTransferStreamType.MessageContent; // Record the FastTransferOperation downloadInfo.RelatedFastTransferOperation = EnumFastTransferOperation.FastTransferSourceCopyProperties; priorDownloadOperation = PriorDownloadOperation.RopFastTransferSourceCopyProperties; // Set value for new download context. downloadInfo.CopyPropertiesCopyFlag = copyFlag; downloadInfo.Property = propertyTags; downloadInfo.Sendoptions = option; downloadInfo.RelatedObjectHandleIndex = objHandleIndex; downloadInfo.ObjectType = ObjectType.Message; downloadInfo.IsLevelTrue = level; // Add new download context to DownloadContextContainer. changeConnection.DownloadContextContainer = changeConnection.DownloadContextContainer.Add(downloadInfo); } else if (handleType == InputHandleType.FolderHandle) { // Find current folder. foreach (AbstractFolder temp in changeConnection.FolderContainer) { if (temp.FolderHandleIndex == objHandleIndex) { isObjExist = true; } } Condition.IsTrue(isObjExist); // Set value for new download context. downloadContextHandleIndex = AdapterHelper.GetHandleIndex(); downloadInfo.DownloadHandleIndex = downloadContextHandleIndex; downloadInfo.AbstractFastTransferStreamType = FastTransferStreamType.folderContent; // Record the FastTransferOperation downloadInfo.RelatedFastTransferOperation = EnumFastTransferOperation.FastTransferSourceCopyProperties; priorDownloadOperation = PriorDownloadOperation.RopFastTransferSourceCopyProperties; // Set value for new download context. downloadInfo.CopyPropertiesCopyFlag = copyFlag; downloadInfo.Property = propertyTags; downloadInfo.Sendoptions = option; downloadInfo.RelatedObjectHandleIndex = objHandleIndex; downloadInfo.ObjectType = ObjectType.Folder; // Add new download context to DownloadContextContainer. changeConnection.DownloadContextContainer = changeConnection.DownloadContextContainer.Add(downloadInfo); } else { // Find the current Attachment foreach (AbstractAttachment temp in changeConnection.AttachmentContainer) { if (temp.AttachmentHandleIndex == objHandleIndex) { isObjExist = true; } } Condition.IsTrue(isObjExist); // Set value for new download context. downloadContextHandleIndex = AdapterHelper.GetHandleIndex(); downloadInfo.DownloadHandleIndex = downloadContextHandleIndex; downloadInfo.AbstractFastTransferStreamType = FastTransferStreamType.attachmentContent; // Record the FastTransferOperation downloadInfo.RelatedFastTransferOperation = EnumFastTransferOperation.FastTransferSourceCopyProperties; priorDownloadOperation = PriorDownloadOperation.RopFastTransferSourceCopyProperties; // Set value for new download context. downloadInfo.CopyPropertiesCopyFlag = copyFlag; downloadInfo.Property = propertyTags; downloadInfo.Sendoptions = option; downloadInfo.ObjectType = ObjectType.Attachment; downloadInfo.RelatedObjectHandleIndex = objHandleIndex; // Add new download context to DownloadContextContainer. changeConnection.DownloadContextContainer = changeConnection.DownloadContextContainer.Add(downloadInfo); } connections.Add(serverId, changeConnection); result = RopResult.Success; // If the server returns success result, it means the RopFastTransferSourceCopyProperties ROP initializes the FastTransfer operation successfully. And then this requirement can be captured. ModelHelper.CaptureRequirement( 431, @"[In RopFastTransferSourceCopyProperties ROP] The RopFastTransferSourceCopyProperties ROP ([MS-OXCROPS] section 2.2.12.7) initializes a FastTransfer operation to download content from a specified messaging object and its descendant sub objects."); } return result; }
/// <summary> /// Initializes a FastTransfer operation to download content from a given messaging object and its descendant subobjects. /// </summary> /// <param name="serverId">A 32-bit signed integer represent the Identity of server.</param> /// <param name="sourceHandleIndex">Folder or message object handle index. </param> /// <param name="handleType">Type of object handle </param> /// <param name="level">Variable indicate whether copy the descendant subobjects.</param> /// <param name="copyFlag">Defines parameters of the FastTransfer download operation.</param> /// <param name="option">Defines the parameters of a download operation.</param> /// <param name="propertyTags">Array of properties and subobjects to exclude.</param> /// <param name="copyToHandleIndex">The properties handle index.</param> /// <returns>Indicate the result of this ROP operation.</returns> public RopResult FastTransferSourceCopyTo(int serverId, int sourceHandleIndex, InputHandleType handleType, bool level, CopyToCopyFlags copyFlag, SendOptionAlls option, Sequence<string> propertyTags, out int copyToHandleIndex) { // Initialize ROP returned value. RopResult result = RopResult.InvalidParameter; copyToHandleIndex = -1; ushort propertyCount = (ushort)propertyTags.Count; this.currentCopyFlag = copyFlag; // Get stream type. switch (handleType) { case InputHandleType.FolderHandle: this.streamType = FastTransferStreamType.folderContent; break; case InputHandleType.MessageHandle: this.streamType = FastTransferStreamType.MessageContent; break; case InputHandleType.AttachmentHandle: this.streamType = FastTransferStreamType.attachmentContent; break; default: break; } // Initialize input propertyTags PropertyTag[] messagePropertyTags = new PropertyTag[propertyCount]; for (int i = 0; i < propertyCount; i++) { messagePropertyTags[i] = this.propertyTagsDictionary[propertyTags[i]]; } // Stores the values for further verification this.previousOperation = EnumFastTransferOperation.FastTransferSourceCopyTo; this.propertyTags = messagePropertyTags; // Construct ROP request. uint sourceHandle = this.handleContainer[sourceHandleIndex]; RopFastTransferSourceCopyToRequest request; request.RopId = 0x4D; request.LogonId = 0X00; request.InputHandleIndex = 0x00; request.OutputHandleIndex = 0x01; // This value specifies the level at which the copy is occurring,Non-Zero: exclude all descendant subobjects from being copied request.Level = level ? (byte)1 : (byte)0; request.CopyFlags = (uint)copyFlag; request.SendOptions = (byte)option; request.PropertyTagCount = propertyCount; request.PropertyTags = messagePropertyTags; // Send request and get response. RopFastTransferSourceCopyToResponse response = (RopFastTransferSourceCopyToResponse)this.Process(serverId, request, sourceHandle); result = (RopResult)response.ReturnValue; if (result == RopResult.Success) { copyToHandleIndex = AdapterHelper.GetHandleIndex(); this.handleContainer.Add(copyToHandleIndex, this.responseSOHs[response.OutputHandleIndex]); } // Verify ROP FastTransferSourceCopyTo this.VerifyRopFastTransferSourceCopyTo(request, response); return result; }
public static RopResult FastTransferSourceCopyTo(int serverId, int objHandleIndex, InputHandleType handleType, bool level, CopyToCopyFlags copyFlag, SendOptionAlls option, Sequence<string> propertyTags, out int downloadContextHandleIndex) { // The contraction conditions. Condition.IsTrue(connections.Count > 0); Condition.IsTrue(connections.Keys.Contains(serverId)); // Initialize the return value. RopResult result = RopResult.InvalidParameter; // The copyFlag conditions. if (((copyFlag == CopyToCopyFlags.Invalid && (requirementContainer.ContainsKey(3445) && requirementContainer[3445])) || (option == SendOptionAlls.Invalid && (requirementContainer.ContainsKey(3463) && requirementContainer[3463]))) || ((copyFlag & CopyToCopyFlags.Move) == CopyToCopyFlags.Move && (requirementContainer.ContainsKey(3442001) && requirementContainer[3442001])) || ((copyFlag & CopyToCopyFlags.Move) == CopyToCopyFlags.Move && (requirementContainer.ContainsKey(3442003) && requirementContainer[3442003]))) { downloadContextHandleIndex = -1; if ((copyFlag & CopyToCopyFlags.Move) == CopyToCopyFlags.Move) { // CopyToCopyFlags value is Move. if (requirementContainer.ContainsKey(3442001) && requirementContainer[3442001]) { // When the ROP return invalid parameter this requirement verified. ModelHelper.CaptureRequirement( 3442001, @"[In Appendix A: Product Behavior] Implementation does not support. <31> Section 3.2.5.8.1.1: Exchange 2010 and Exchange 2013 do not support the Move flag for the RopFastTransferSourceCopyTo ROP (section 2.2.3.1.1.1)."); } if (requirementContainer.ContainsKey(3442003) && requirementContainer[3442003]) { result = RopResult.InvalidParameter; // When the ROP return invalid parameter this requirement verified. ModelHelper.CaptureRequirement( 3442003, @"[In Appendix A: Product Behavior] If the server receives the Move flag, implementation does fail the operation with an error code InvalidParameter (0x80070057). <31> Section 3.2.5.8.1.1: The server sets the value of the ReturnValue field to InvalidParameter (0x80070057) if it receives this flag [Move flag].(Microsoft Exchange Server 2010, Exchange Server 2013 and Exchange Server 2016 follow this behavior.)"); } } return result; } else { // Create a new download context AbstractDownloadInfo downloadInfo = new AbstractDownloadInfo(); bool isObjExist = false; // Get value of ConnectionData ConnectionData changeConnection = connections[serverId]; connections.Remove(serverId); // Find current message if (handleType == InputHandleType.MessageHandle) { foreach (AbstractMessage temp in changeConnection.MessageContainer) { if (temp.MessageHandleIndex == objHandleIndex) { isObjExist = true; } } Condition.IsTrue(isObjExist); // Set value for new download context. downloadInfo.DownloadHandleIndex = AdapterHelper.GetHandleIndex(); downloadContextHandleIndex = downloadInfo.DownloadHandleIndex; downloadInfo.Sendoptions = option; downloadInfo.Property = propertyTags; downloadInfo.CopyToCopyFlag = copyFlag; downloadInfo.IsLevelTrue = level; // Record FastTransfer Operation. downloadInfo.RelatedFastTransferOperation = EnumFastTransferOperation.FastTransferSourceCopyTo; downloadInfo.AbstractFastTransferStreamType = FastTransferStreamType.MessageContent; downloadInfo.ObjectType = ObjectType.Message; downloadInfo.RelatedObjectHandleIndex = objHandleIndex; priorDownloadOperation = PriorDownloadOperation.RopFastTransferSourceCopyTo; // Add new download context to downloadContext Container. changeConnection.DownloadContextContainer = changeConnection.DownloadContextContainer.Add(downloadInfo); } else if (handleType == InputHandleType.FolderHandle) { // Find current folder. foreach (AbstractFolder temp in changeConnection.FolderContainer) { if (temp.FolderHandleIndex == objHandleIndex) { isObjExist = true; } } Condition.IsTrue(isObjExist); // Set value for new download context. downloadInfo.DownloadHandleIndex = AdapterHelper.GetHandleIndex(); downloadContextHandleIndex = downloadInfo.DownloadHandleIndex; downloadInfo.Sendoptions = option; downloadInfo.Property = propertyTags; downloadInfo.CopyToCopyFlag = copyFlag; // Record FastTransfer Operation downloadInfo.RelatedFastTransferOperation = EnumFastTransferOperation.FastTransferSourceCopyTo; downloadInfo.AbstractFastTransferStreamType = FastTransferStreamType.folderContent; downloadInfo.ObjectType = ObjectType.Folder; downloadInfo.RelatedObjectHandleIndex = objHandleIndex; priorDownloadOperation = PriorDownloadOperation.RopFastTransferSourceCopyTo; // Add new download context to DownloadContextContainer changeConnection.DownloadContextContainer = changeConnection.DownloadContextContainer.Add(downloadInfo); } else { // Find current attachment foreach (AbstractAttachment temp in changeConnection.AttachmentContainer) { if (temp.AttachmentHandleIndex == objHandleIndex) { isObjExist = true; } } Condition.IsTrue(isObjExist); // Set value for new download context. downloadInfo.DownloadHandleIndex = AdapterHelper.GetHandleIndex(); downloadContextHandleIndex = downloadInfo.DownloadHandleIndex; downloadInfo.Sendoptions = option; downloadInfo.Property = propertyTags; downloadInfo.CopyToCopyFlag = copyFlag; // Record FastTransfer Operation downloadInfo.RelatedFastTransferOperation = EnumFastTransferOperation.FastTransferSourceCopyTo; downloadInfo.AbstractFastTransferStreamType = FastTransferStreamType.attachmentContent; downloadInfo.ObjectType = ObjectType.Attachment; downloadInfo.RelatedObjectHandleIndex = objHandleIndex; priorDownloadOperation = PriorDownloadOperation.RopFastTransferSourceCopyTo; // Add new download context to DownloadContextContainer changeConnection.DownloadContextContainer = changeConnection.DownloadContextContainer.Add(downloadInfo); } connections.Add(serverId, changeConnection); result = RopResult.Success; ModelHelper.CaptureRequirement( 361, @"[In RopFastTransferSourceCopyTo ROP] The RopFastTransferSourceCopyTo ROP ([MS-OXCROPS] section 2.2.12.6) initializes a FastTransfer operation to download content from a given messaging object and its descendant subobjects."); if ((copyFlag & CopyToCopyFlags.Move) == CopyToCopyFlags.Move) { if (requirementContainer.ContainsKey(3442002) && requirementContainer[3442002]) { ModelHelper.CaptureRequirement( 3442002, @"[In Appendix A: Product Behavior] Implementation does support Move flag [for the RopFastTransferSourceCopyTo ROP]. (Microsoft Exchange Server 2007 follow this behavior.)"); } if (requirementContainer.ContainsKey(3442004) && requirementContainer[3442004]) { ModelHelper.CaptureRequirement( 3442004, @"[In Appendix A: Product Behavior] If the server receives the Move flag, implementation does not fail the operation.(<31> Section 3.2.5.8.1.1: Microsoft Exchange Server 2007 follows this behavior.)"); } } } return result; }