/// <summary>
        /// Define the scope and parameters of the synchronization download operation. 
        /// </summary>
        /// <param name="serverId">A 32-bit signed integer represent the Identity of server.</param>
        /// <param name="folderHandleIndex">The server object handle index.</param>
        /// <param name="synchronizationType">The type of synchronization requested: contents or hierarchy.</param>
        /// <param name="option">Defines the parameters of a download operation.</param>
        /// <param name="synchronizationFlag">Flag structure that defines the parameters of the synchronization operation.</param>
        /// <param name="synchronizationExtraFlag">Extra flag structure that defines the parameters of the synchronization operation.</param>
        /// <param name="property">A list of properties and subobjects to exclude or include.</param>
        /// <param name="downloadcontextHandleIndex">Synchronization download context handle index.</param>
        /// <returns>Indicate the result of this ROP operation.</returns>
        public RopResult SynchronizationConfigure(int serverId, int folderHandleIndex, SynchronizationTypes synchronizationType, SendOptionAlls option, SynchronizationFlag synchronizationFlag, SynchronizationExtraFlag synchronizationExtraFlag, Sequence<string> property, out int downloadcontextHandleIndex)
        {
            // Initialize ROP data.
            downloadcontextHandleIndex = -1;
            uint objHandle = this.handleContainer[folderHandleIndex];
            RopSynchronizationConfigureRequest synchronizationConfigureRequest;
            RopResult result = RopResult.InvalidParameter;
            switch (synchronizationType)
            {
                case SynchronizationTypes.Hierarchy:
                    this.streamType = FastTransferStreamType.hierarchySync;
                    break;
                case SynchronizationTypes.Contents:
                    this.streamType = FastTransferStreamType.contentsSync;
                    break;
                default:
                    break;
            }

            PropertyTag[] propertyTags = new PropertyTag[property.Count];
            for (int i = 0; i < property.Count; i++)
            {
                propertyTags[i] = this.propertyTagsDictionary[property[i]];
            }

            this.synchroniztionFlag = synchronizationFlag;
            this.propertyTagForConfigure = propertyTags[0];

            // Construct RopSynchronizationConfigure request.
            synchronizationConfigureRequest.RopId = (byte)RopId.RopSynchronizationConfigure;
            synchronizationConfigureRequest.LogonId = 0x00;
            synchronizationConfigureRequest.InputHandleIndex = 0x00;
            synchronizationConfigureRequest.OutputHandleIndex = 0x01;

            // 0x01,Indicates a contents synchronization.0x02,Indicates a hierarchy synchronization.
            synchronizationConfigureRequest.SynchronizationType = (byte)synchronizationType;
            synchronizationConfigureRequest.SendOptions = (byte)option;

            // Unicode 
            synchronizationConfigureRequest.SynchronizationFlags = (ushort)synchronizationFlag;
            if (synchronizationType == SynchronizationTypes.Contents)
            {
                // Set RestrictionDataSize to 0x0000 to avoid the complex RestrictionData.
                synchronizationConfigureRequest.RestrictionDataSize = 0x0005;

                // If PidTagMessageClass exists 
                synchronizationConfigureRequest.RestrictionData = new byte[] { 0x08, 0x1f, 0x00, 0x1a, 0x00 };
            }
            else
            {
                // Set RestrictionDataSize to 0x0000 to avoid the complex RestrictionData.
                synchronizationConfigureRequest.RestrictionDataSize = 0x0000;
                synchronizationConfigureRequest.RestrictionData = new byte[0];
            }

            synchronizationConfigureRequest.SynchronizationExtraFlags = (byte)synchronizationExtraFlag;
            synchronizationConfigureRequest.PropertyTagCount = (ushort)propertyTags.Length;
            synchronizationConfigureRequest.PropertyTags = propertyTags;

            if (this.Process(serverId, synchronizationConfigureRequest, objHandle) is RopSynchronizationConfigureResponse)
            {
                // Send request and get response.
                RopSynchronizationConfigureResponse synchronizationConfigureResponse = (RopSynchronizationConfigureResponse)this.Process(serverId, synchronizationConfigureRequest, objHandle);
                result = (RopResult)synchronizationConfigureResponse.ReturnValue;

                if (result == RopResult.Success)
                {
                    downloadcontextHandleIndex = AdapterHelper.GetHandleIndex();
                    this.handleContainer.Add(downloadcontextHandleIndex, this.responseSOHs[synchronizationConfigureResponse.OutputHandleIndex]);

                    if ((synchronizationExtraFlag & SynchronizationExtraFlag.OrderByDeliveryTime) != SynchronizationExtraFlag.OrderByDeliveryTime)
                    {
                        this.isOrderByDeliveryTimeExtraFlagNotSet = true;
                    }

                    if (this.lastChangeMadeByServer && (synchronizationExtraFlag & SynchronizationExtraFlag.CN) == SynchronizationExtraFlag.CN)
                    {
                        this.lastChangeMadeByClient = true;
                    }
                }

                // Verify ROP SynchronizationConfigure
                this.VerifyRopSynchronizationConfigure(synchronizationConfigureRequest, synchronizationConfigureResponse);
            }
            else
            {
                // If the response type is not RopSynchronizationConfigureResponse it must be that the process method throughout a FormatException when sending RPC request buffer.
                result = RopResult.RpcFormat;
            }

            return result;
        }
Esempio n. 2
0
        public static RopResult SynchronizationConfigure(int serverId, int folderHandleIndex, SynchronizationTypes synchronizationType, SendOptionAlls option, SynchronizationFlag synchronizationFlag, SynchronizationExtraFlag synchronizationExtraFlag, Sequence<string> property, out int downloadcontextHandleIndex)
        {
            // The contractions conditions.
            Condition.IsTrue(connections.Count > 0);
            Condition.IsTrue(connections.Keys.Contains(serverId));
            Condition.IsTrue(connections[serverId].FolderContainer.Count > 0);

            // Initialize return value.
            RopResult result = RopResult.Success;
            downloadcontextHandleIndex = -1;

            if ((option & SendOptionAlls.Invalid) == SendOptionAlls.Invalid && (requirementContainer.ContainsKey(3463) && requirementContainer[3463]))
            {
                result = RopResult.InvalidParameter;
                return result;
            }

            // SynchronizationFlag MUST match the value of the Unicode flag from SendOptions field.
            if ((synchronizationFlag & SynchronizationFlag.Unicode) == SynchronizationFlag.Unicode)
            {
                Condition.IsTrue((option & SendOptionAlls.Unicode) == SendOptionAlls.Unicode);
            }

            // When SynchronizationType is 0X04 then Servers return 0x80070057.
            if (synchronizationType == SynchronizationTypes.InvalidParameter)
            {
                if (requirementContainer.ContainsKey(2695) && requirementContainer[2695])
                {
                    result = RopResult.NotSupported;
                }
                else
                {
                    result = RopResult.InvalidParameter;
                    ModelHelper.CaptureRequirement(2695, "[In Receiving a RopSynchronizationConfigure ROP Request] [SynchronizationType Constraints] Servers MUST return 0x80070057 if SynchronizationType is 0x04.");
                }
            }
            else if ((synchronizationFlag & SynchronizationFlag.Reserved) == SynchronizationFlag.Reserved)
            {
                // When SynchronizationType is Reserved then Servers MUST fail the ROP request.
                result = RopResult.RpcFormat;
                ModelHelper.CaptureRequirement(2180, "[In Receiving a RopSynchronizationConfigure ROP Request] [SynchronizationType Constraints] The server MUST fail the ROP request if the Reserved flag of the SynchronizationFlags field is set.");
            }
            else
            {
                // Get ConnectionData value.
                ConnectionData changeConnection = connections[serverId];

                // Identify whether the CurrentFolder is existent or not.
                bool isCurrentFolderExist = false;

                // Identify whether the Current Folder is existent or not.
                foreach (AbstractFolder tempfolder in changeConnection.FolderContainer)
                {
                    if (tempfolder.FolderHandleIndex == folderHandleIndex)
                    {
                        // Set the value to the variable when the current folder is existent.
                        isCurrentFolderExist = true;
                    }
                }

                // The condition of CurrentFolder is existent.
                if (isCurrentFolderExist)
                {
                    // Initialize the Download information.
                    AbstractDownloadInfo abstractDownloadInfo = new AbstractDownloadInfo
                    {
                        UpdatedState =
                            new AbstractUpdatedState
                            {
                                CnsetRead = new Set<int>(),
                                CnsetSeen = new Set<int>(),
                                CnsetSeenFAI = new Set<int>(),
                                IdsetGiven = new Set<int>()
                            },
                        DownloadHandleIndex = AdapterHelper.GetHandleIndex()
                    };

                    // Get the download Handle for download context.
                    downloadcontextHandleIndex = abstractDownloadInfo.DownloadHandleIndex;
                    ModelHelper.CaptureRequirement(669, "[In RopSynchronizationConfigure ROP Response Buffer]OutputServerObject: This value MUST be the synchronization download context.");

                    // Record the flags.
                    abstractDownloadInfo.Sendoptions = option;
                    abstractDownloadInfo.SynchronizationType = synchronizationType;
                    abstractDownloadInfo.Synchronizationflag = synchronizationFlag;
                    abstractDownloadInfo.SynchronizationExtraflag = synchronizationExtraFlag;

                    // Record the Property.
                    abstractDownloadInfo.Property = property;

                    // Record folder handle of related to the download context. 
                    abstractDownloadInfo.RelatedObjectHandleIndex = folderHandleIndex;
                    switch (synchronizationType)
                    {
                        // Record synchronizationType value for condition of Synchronization type is Contents.
                        case SynchronizationTypes.Contents:
                            abstractDownloadInfo.AbstractFastTransferStreamType = FastTransferStreamType.contentsSync;
                            abstractDownloadInfo.ObjectType = ObjectType.Folder;
                            break;

                        // Record synchronizationType value for condition of Synchronization type is Hierarchy.
                        case SynchronizationTypes.Hierarchy:
                            abstractDownloadInfo.AbstractFastTransferStreamType = FastTransferStreamType.hierarchySync;
                            abstractDownloadInfo.ObjectType = ObjectType.Folder;
                            break;
                        default:

                            // Condition ofsynchronizationType is invalid parameter.
                            result = RopResult.InvalidParameter;
                            break;
                    }

                    // Condition of the operation return success.
                    if (result == RopResult.Success)
                    {
                        // Add the  new value to DownloadContextContainer.
                        changeConnection.DownloadContextContainer = changeConnection.DownloadContextContainer.Add(abstractDownloadInfo);
                        connections[serverId] = changeConnection;
                        priorDownloadOperation = PriorDownloadOperation.RopSynchronizationConfigure;
                        priorOperation = MS_OXCFXICS.PriorOperation.RopSynchronizationConfigure;

                        ModelHelper.CaptureRequirement(
                            641,
                            @"[In RopSynchronizationConfigure] The RopSynchronizationConfigure ROP ([MS-OXCROPS] section 2.2.13.1) is used to define the synchronization scope and parameters of the synchronization download operation.");
                    }
                }
            }

            return result;
        }