/// <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;
        }
Exemplo n.º 2
0
        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;
        }
Exemplo n.º 4
0
        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;
        }