public void MSOXCFOLD_S03_TC08_SetAndGetProperties()
        {
            this.CheckWhetherSupportTransport();
            this.Adapter.DoConnect(ConnectionType.PrivateMailboxServer);
            this.GenericFolderInitialization();

            #region Step 1. The client calls RopCreateFolder to create [MSOXCFOLDSubfolder1] under the root folder.

            RopCreateFolderRequest createFolderRequest = new RopCreateFolderRequest
            {
                RopId = (byte)RopId.RopCreateFolder,
                LogonId = Constants.CommonLogonId,
                InputHandleIndex = Constants.CommonInputHandleIndex,
                OutputHandleIndex = Constants.CommonOutputHandleIndex,
                FolderType = 0x01,
                UseUnicodeStrings = 0x1,
                OpenExisting = 0x00,
                Reserved = 0x0,
                DisplayName = Encoding.Unicode.GetBytes(Constants.Subfolder1),
                Comment = Encoding.Unicode.GetBytes(Constants.Subfolder1)
            };

            RopCreateFolderResponse createFolderResponse = this.Adapter.CreateFolder(createFolderRequest, this.RootFolderHandle, ref this.responseHandles);
            Site.Assert.AreEqual<uint>(Constants.SuccessCode, createFolderResponse.ReturnValue, "RopCreateFolder ROP operation performs successfully!");
            ulong subfolderId1 = createFolderResponse.FolderId;
            uint subfolderHandle1 = this.responseHandles[0][createFolderResponse.OutputHandleIndex];

            #endregion

            #region Step 2. The client calls RopCreateFolder to create [MSOXCFOLDSubfolder2] under the root folder.

            createFolderRequest.FolderType = 0x02;
            createFolderRequest.DisplayName = Encoding.Unicode.GetBytes(Constants.Subfolder2);
            createFolderRequest.Comment = Encoding.Unicode.GetBytes(Constants.StringNullTerminated);

            createFolderResponse = this.Adapter.CreateFolder(createFolderRequest, this.RootFolderHandle, ref this.responseHandles);
            Site.Assert.AreEqual<uint>(Constants.SuccessCode, createFolderResponse.ReturnValue, "RopCreateFolder ROP operation performs successfully!");
            uint subfolderHandle2 = this.responseHandles[0][createFolderResponse.OutputHandleIndex];

            #endregion

            #region Step 3. The client creates a Non-FAI message and saves it in [MSOXCFOLDSubfolder1].

            uint messageHandle1 = 0;
            ulong messageId1 = 0;
            this.CreateSaveMessage(subfolderHandle1, subfolderId1, ref messageId1, ref messageHandle1);

            #endregion

            #region Step 4. The client create a FAI message and saves it in [MSOXCFOLDSubfolder2].

            uint messageHandle2 = 0;
            ulong messageId2 = 0;
            this.CreateSaveMessage(subfolderHandle2, subfolderId1, 0x01, ref messageId2, ref messageHandle2);

            #endregion

            #region Step 5. The client get the properties from the [MSOXCFOLDSubfolder1] under the root folder.

            PropertyTag[] tags = new PropertyTag[7];
            PropertyTag tag;

            tag.PropertyId = (ushort)FolderPropertyId.PidTagAttributeHidden;
            tag.PropertyType = (ushort)PropertyType.PtypBoolean;
            tags[0] = tag;

            tag.PropertyId = (ushort)FolderPropertyId.PidTagComment;
            tag.PropertyType = (ushort)PropertyType.PtypString;
            tags[1] = tag;

            tag.PropertyId = (ushort)FolderPropertyId.PidTagContainerClass;
            tag.PropertyType = (ushort)PropertyType.PtypString;
            tags[2] = tag;

            tag.PropertyId = (ushort)FolderPropertyId.PidTagDisplayName;
            tag.PropertyType = (ushort)PropertyType.PtypString;
            tags[3] = tag;

            tag.PropertyId = (ushort)FolderPropertyId.PidTagFolderType;
            tag.PropertyType = (ushort)PropertyType.PtypInteger32;
            tags[4] = tag;

            tag.PropertyId = (ushort)FolderPropertyId.PidTagRights;
            tag.PropertyType = (ushort)PropertyType.PtypInteger32;
            tags[5] = tag;

            tag.PropertyId = (ushort)FolderPropertyId.PidTagAccessControlListData;
            tag.PropertyType = (ushort)PropertyType.PtypBinary;
            tags[6] = tag;

            RopGetPropertiesSpecificRequest getPropertiesSpecificRequest = new RopGetPropertiesSpecificRequest();
            RopGetPropertiesSpecificResponse getPropertiesSpecificResponse = new RopGetPropertiesSpecificResponse();
            getPropertiesSpecificRequest.RopId = (byte)RopId.RopGetPropertiesSpecific;
            getPropertiesSpecificRequest.LogonId = Constants.CommonLogonId;
            getPropertiesSpecificRequest.InputHandleIndex = Constants.CommonInputHandleIndex;
            getPropertiesSpecificRequest.PropertySizeLimit = 0xFFFF;
            getPropertiesSpecificRequest.PropertyTagCount = (ushort)tags.Length;
            getPropertiesSpecificRequest.PropertyTags = tags;
            getPropertiesSpecificRequest.WantUnicode = 0x01;
            getPropertiesSpecificResponse = this.Adapter.GetFolderObjectSpecificProperties(getPropertiesSpecificRequest, subfolderHandle1, ref this.responseHandles);
            Site.Assert.AreEqual<uint>(0, getPropertiesSpecificResponse.ReturnValue, "RopGetPropertiesSpecific ROP operation performs successfully!");
            RopGetPropertiesSpecificResponse getPropertiesSpecificResponse1 = getPropertiesSpecificResponse;

            #region Verify the requirements: MS_OXCFOLD_R1033, MS-OXCFOLD_R10359, and MS-OXCFOLD_R811.

            // Add the debug information.
            Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCFOLD_R1033");

            // Verify MS-OXCFOLD requirement: MS-OXCFOLD_R1033.
            Site.CaptureRequirementIfAreEqual<byte>(
                0,
                getPropertiesSpecificResponse.RowData.PropertyValues[0].Value[0],
                1033,
                @"[In PidTagAttributeHidden Property] The value is zero otherwise [If the folder is not hidden].");

            // Add the debug information
            Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCFOLD_R10359");

            // Verify MS-OXCFOLD requirement: MS-OXCFOLD_R10359
            Site.CaptureRequirementIfAreEqual<string>(
                Constants.Subfolder1,
                Encoding.Unicode.GetString(getPropertiesSpecificResponse.RowData.PropertyValues[1].Value),
                10359,
                @"[In PidTagComment Property] The PidTagComment property ([MS-OXPROPS] section 2.628) contains a comment about the purpose or content of the folder.");

            // Add the debug information
            Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCFOLD_R811");

            // Verify MS-OXCFOLD requirement: MS-OXCFOLD_R811
            Site.CaptureRequirementIfAreEqual<int>(
                1,
                BitConverter.ToInt32(getPropertiesSpecificResponse.RowData.PropertyValues[4].Value, 0),
                811,
                @"[In PidTagFolderType Property] FOLDER_GENERIC (1): A generic folder that contains messages and other folders.");
            #endregion

            #endregion

            #region Step 6. The client set the read/write properties for the folder.

            TaggedPropertyValue[] taggedPropertyValueArray = new TaggedPropertyValue[6];
            PropertyTag tempPropertyTag = new PropertyTag();
            int size = 0;

            // Set PidTagAttributeHidden property for the folder.
            taggedPropertyValueArray[0] = new TaggedPropertyValue();
            tempPropertyTag.PropertyId = (ushort)FolderPropertyId.PidTagAttributeHidden;
            tempPropertyTag.PropertyType = (ushort)PropertyType.PtypBoolean;
            taggedPropertyValueArray[0].PropertyTag = tempPropertyTag;
            taggedPropertyValueArray[0].Value = new byte[1] { 0x01 };

            // Set PidTagComment property for the folder.
            taggedPropertyValueArray[1] = new TaggedPropertyValue();
            tempPropertyTag.PropertyId = (ushort)FolderPropertyId.PidTagComment;
            tempPropertyTag.PropertyType = (ushort)PropertyType.PtypString;
            taggedPropertyValueArray[1].PropertyTag = tempPropertyTag;
            taggedPropertyValueArray[1].Value = Encoding.Unicode.GetBytes(Constants.Subfolder3);

            // Set PidTagContainerClass property for the folder.
            taggedPropertyValueArray[2] = new TaggedPropertyValue();
            tempPropertyTag.PropertyId = (ushort)FolderPropertyId.PidTagContainerClass;
            tempPropertyTag.PropertyType = (ushort)PropertyType.PtypString;
            taggedPropertyValueArray[2].PropertyTag = tempPropertyTag;
            taggedPropertyValueArray[2].Value = Encoding.Unicode.GetBytes("IPF.Note\0");

            // Set PidTagDisplayName property for the folder.
            taggedPropertyValueArray[3] = new TaggedPropertyValue();
            tempPropertyTag.PropertyId = (ushort)FolderPropertyId.PidTagDisplayName;
            tempPropertyTag.PropertyType = (ushort)PropertyType.PtypString;
            taggedPropertyValueArray[3].PropertyTag = tempPropertyTag;
            taggedPropertyValueArray[3].Value = Encoding.Unicode.GetBytes(Constants.Subfolder3);

            // Set PidTagFolderType property for the folder.
            taggedPropertyValueArray[4] = new TaggedPropertyValue();
            tempPropertyTag.PropertyId = (ushort)FolderPropertyId.PidTagFolderType;
            tempPropertyTag.PropertyType = (ushort)PropertyType.PtypInteger32;
            taggedPropertyValueArray[4].PropertyTag = tempPropertyTag;
            taggedPropertyValueArray[4].Value = BitConverter.GetBytes(0x00000001);

            // Set PidTagRights property for the folder.
            taggedPropertyValueArray[5] = new TaggedPropertyValue();
            tempPropertyTag.PropertyId = (ushort)FolderPropertyId.PidTagRights;
            tempPropertyTag.PropertyType = (ushort)PropertyType.PtypInteger32;
            taggedPropertyValueArray[5].PropertyTag = tempPropertyTag;
            taggedPropertyValueArray[5].Value = BitConverter.GetBytes(0x00000400);

            for (int i = 0; i < taggedPropertyValueArray.Length; i++)
            {
                size += taggedPropertyValueArray[i].Size();
            }

            RopSetPropertiesRequest setPropertiesRequest = new RopSetPropertiesRequest
            {
                RopId = (byte)RopId.RopSetProperties,
                LogonId = Constants.CommonLogonId,
                InputHandleIndex = Constants.CommonInputHandleIndex,
                PropertyValueSize = (ushort)(size + 2),
                PropertyValueCount = (ushort)taggedPropertyValueArray.Length,
                PropertyValues = taggedPropertyValueArray
            };

            RopSetPropertiesResponse setPropertiesResponse = this.Adapter.SetFolderObjectProperties(setPropertiesRequest, subfolderHandle1, ref this.responseHandles);
            Site.Assert.AreEqual<uint>(0, setPropertiesResponse.ReturnValue, "RopSetProperties ROP operation performs successfully!");

            #endregion

            #region Step 7. The client get the properties from the [MSOXCFOLDSubfolder1] under the root folder after execute the RopSetProperties operation.

            getPropertiesSpecificResponse = this.Adapter.GetFolderObjectSpecificProperties(getPropertiesSpecificRequest, subfolderHandle1, ref this.responseHandles);
            Site.Assert.AreEqual<uint>(0, getPropertiesSpecificResponse.ReturnValue, "RopGetPropertiesSpecific ROP operation performs successfully!");

            #region Verify the requirements: MS_OXCFOLD_R1032, MS-OXCFOLD_R10356.

            // Add the debug information
            Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCFOLD_R1032");

            // Verify MS-OXCFOLD requirement: MS-OXCFOLD_R1032.
            Site.CaptureRequirementIfAreNotEqual<byte>(
                0,
                getPropertiesSpecificResponse.RowData.PropertyValues[0].Value[0],
                1032,
                @"[In PidTagAttributeHidden Property] The value of this property [PidTagAttributeHidden] is nonzero if the folder is hidden.");

            // Add the debug information
            Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCFOLD_R10356");

            // MS-OXCFOLD_R1032 and MS-OXCFOLD_R1033 were verified, MS-OXCFOLD_R10356 can be verified directly.
            Site.CaptureRequirement(
                10356,
                @"[In PidTagAttributeHidden Property] The PidTagAttributeHidden property ([MS-OXPROPS] section 2.602) specifies whether the folder is hidden.");

            string pidTagContainerClass = System.Text.Encoding.Unicode.GetString(getPropertiesSpecificResponse.RowData.PropertyValues[2].Value);
            
            // Add the debug information
            this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCFOLD_R1038: the PidTagContainerClass property value is {0}", pidTagContainerClass.Replace("\0", string.Empty));
        
            // Verify MS-OXCFOLD requirement: MS-OXCFOLD_R1038
            this.Site.CaptureRequirementIfIsTrue(
                pidTagContainerClass.StartsWith("IPF."),
                1038,
                @"[In PidTagContainerClass Property] The value of this property [PidTagContainerClass] MUST begin with ""IPF."".");

            // According to step above, the folder object includes the PidTagContainerClass property and the value of the PidTagContainerClass property follow the definition in Open Specification.
            // So R10036 will be verfied.
            this.Site.CaptureRequirement(
                10036,
                @"[In PidTagContainerClass Property] The PidTagContainerClass property ([MS-OXPROPS] section 2.633) specifies the type of Message object that the folder contains.");
            #endregion

            #endregion

            #region Step 8. The client get the properties from the [MSOXCFOLDSubfolder2] under the root folder.

            getPropertiesSpecificResponse = this.Adapter.GetFolderObjectSpecificProperties(getPropertiesSpecificRequest, subfolderHandle2, ref this.responseHandles);
            Site.Assert.AreEqual<uint>(0, getPropertiesSpecificResponse.ReturnValue, "RopGetPropertiesSpecific ROP operation performs successfully!");
            RopGetPropertiesSpecificResponse getPropertiesSpecificResponse3 = getPropertiesSpecificResponse;

            #region Verify the requirement: MS-OXCFOLD_R812 and  MS-OXCFOLD_R1034.

            // Add the debug information
            Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCFOLD_R812");

            // Verify MS-OXCFOLD requirement: MS-OXCFOLD_R812
            Site.CaptureRequirementIfAreEqual<int>(
                2,
                BitConverter.ToInt32(getPropertiesSpecificResponse.RowData.PropertyValues[4].Value, 0),
                812,
                @"[In PidTagFolderType Property] FOLDER_SEARCH (2): A folder that contains the results of a search, in the form of links to messages that meet search criteria.");

            bool isVerifyR1034 = Encoding.Unicode.GetString(getPropertiesSpecificResponse1.RowData.PropertyValues[1].Value) == Constants.Subfolder1 &&
                Encoding.Unicode.GetString(getPropertiesSpecificResponse3.RowData.PropertyValues[1].Value) == Constants.StringNullTerminated;

            // Add the debug information.
            Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCFOLD_R1034, the property [PidTagComment] is present {0} only if the client sets it.", isVerifyR1034 ? string.Empty : "not");

            // Verify MS-OXCFOLD requirement: MS-OXCFOLD_R1034.
            Site.CaptureRequirementIfIsTrue(
                isVerifyR1034,
                1034,
                @"[In PidTagComment Property] This property [PidTagComment] is present only if the client sets it when the folder is created.");

            #endregion

            #endregion

            #region Step 8. The client set the same read/write properties for the [MSOXCFOLDSubfolder2] as [MSOXCFOLDSubfolder1].
            taggedPropertyValueArray = new TaggedPropertyValue[1];
            tempPropertyTag = new PropertyTag();

            // Set PidTagDisplayName property for the folder.
            taggedPropertyValueArray[0] = new TaggedPropertyValue();
            tempPropertyTag.PropertyId = (ushort)FolderPropertyId.PidTagDisplayName;
            tempPropertyTag.PropertyType = (ushort)PropertyType.PtypString;
            taggedPropertyValueArray[0].PropertyTag = tempPropertyTag;
            taggedPropertyValueArray[0].Value = Encoding.Unicode.GetBytes(Constants.Subfolder3);

            setPropertiesRequest = new RopSetPropertiesRequest
            {
                RopId = (byte)RopId.RopSetProperties,
                LogonId = Constants.CommonLogonId,
                InputHandleIndex = Constants.CommonInputHandleIndex,
                PropertyValueSize = (ushort)(taggedPropertyValueArray[0].Size() + 2),
                PropertyValueCount = (ushort)taggedPropertyValueArray.Length,
                PropertyValues = taggedPropertyValueArray
            };
            setPropertiesResponse = this.Adapter.SetFolderObjectProperties(setPropertiesRequest, subfolderHandle2, ref this.responseHandles);

            // Add the debug information.
            Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCFOLD_R1039");

            // Only set one property in RopSetProperties ROP request, use 0 as index here.
            int expectedIndex = 0;
            bool isVerifiedR1039 = false;
            if (setPropertiesResponse.PropertyProblems != null)
            {
                Site.Log.Add(
                    LogEntryKind.Debug,
                    "The PropertyProblems of index {0} in RopSetProperties ROP response return value is: {1}",
                    expectedIndex,
                    setPropertiesResponse.PropertyProblems[expectedIndex].ErrorCode);
                isVerifiedR1039 = setPropertiesResponse.PropertyProblems[expectedIndex].ErrorCode != Constants.SuccessCode;
            }
            else
            {
                Site.Log.Add(LogEntryKind.Debug, "The RopSetProperties ROP response return value is: {0}", setPropertiesResponse.ReturnValue);
                isVerifiedR1039 = setPropertiesResponse.ReturnValue != Constants.SuccessCode;
            }

            // Verify MS-OXCFOLD requirement: MS-OXCFOLD_R1039.
            Site.CaptureRequirementIfIsTrue(
                isVerifiedR1039,
                1039,
                @"[In PidTagDisplayName Property] Sibling folders MUST have unique display names.");
            #endregion

            #region Step 9. The client calls RopOpenFolder to get the Root folder handle.

            RopOpenFolderRequest openFolderRequest = new RopOpenFolderRequest
            {
                RopId = (byte)RopId.RopOpenFolder,
                LogonId = Constants.CommonLogonId,
                InputHandleIndex = Constants.CommonInputHandleIndex,
                OutputHandleIndex = Constants.CommonOutputHandleIndex,
                FolderId = this.DefaultFolderIds[0],
                OpenModeFlags = (byte)FolderOpenModeFlags.OpenSoftDeleted
            };

            RopOpenFolderResponse openFolderResponse = this.Adapter.OpenFolder(openFolderRequest, this.LogonHandle, ref this.responseHandles);
            Site.Assert.AreEqual<uint>(Constants.SuccessCode, openFolderResponse.ReturnValue, "RopOpenFolder ROP operation performs successfully!");
            uint rootFolderHandle = this.responseHandles[0][openFolderResponse.OutputHandleIndex];

            #endregion

            #region Step 10. The client get the properties from the Root folder.

            getPropertiesSpecificResponse = this.Adapter.GetFolderObjectSpecificProperties(getPropertiesSpecificRequest, rootFolderHandle, ref this.responseHandles);
            Site.Assert.AreEqual<uint>(0, getPropertiesSpecificResponse.ReturnValue, "RopGetPropertiesSpecific ROP operation performs successfully!");

            // Add the debug information.
            Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCFOLD_R810");

            // Verify MS-OXCFOLD requirement: MS-OXCFOLD_R810.
            Site.CaptureRequirementIfAreEqual<int>(
                0,
                BitConverter.ToInt32(getPropertiesSpecificResponse.RowData.PropertyValues[4].Value, 0),
                810,
                @"[In PidTagFolderType Property] FOLDER_ROOT (0): The Root folder of the folder hierarchy table; that is, a folder that has no parent folder.");

            RopGetPropertiesAllResponse getPropertiesAllResponse = this.Adapter.GetFolderPropertiesAll(this.RootFolderHandle, ref this.responseHandles);
            Site.Assert.AreEqual<uint>(0, getPropertiesAllResponse.ReturnValue, "RopGetPropertiesAllResponse ROP operation performs successfully!");
            #endregion

            #region Step 11. The client get property PidTagAddressBookEntryId
            if (Common.IsRequirementEnabled(350002, this.Site))
            {
                PropertyTag[] propertyTagArray = new PropertyTag[1];
                PropertyTag propertyTag = new PropertyTag
                {
                    PropertyId = (ushort)FolderPropertyId.PidTagAddressBookEntryId,
                    PropertyType = (ushort)PropertyType.PtypBinary
                };
                propertyTagArray[0] = propertyTag;

                getPropertiesSpecificRequest = new RopGetPropertiesSpecificRequest();
                getPropertiesSpecificRequest.RopId = (byte)RopId.RopGetPropertiesSpecific;
                getPropertiesSpecificRequest.LogonId = Constants.CommonLogonId;
                getPropertiesSpecificRequest.InputHandleIndex = Constants.CommonInputHandleIndex;
                getPropertiesSpecificRequest.PropertySizeLimit = 0xFFFF;
                getPropertiesSpecificRequest.PropertyTagCount = (ushort)propertyTagArray.Length;
                getPropertiesSpecificRequest.PropertyTags = propertyTagArray;

                getPropertiesSpecificResponse = this.Adapter.GetFolderObjectSpecificProperties(getPropertiesSpecificRequest, subfolderHandle1, ref this.responseHandles);
                Site.Assert.AreEqual<uint>(0, getPropertiesSpecificResponse.ReturnValue, "RopGetPropertiesSpecific ROP operation performs successfully!");

                // Add the debug information.
                Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCFOLD_R350");

                // Verify MS-OXCFOLD requirement: MS-OXCFOLD_R350.
                // Flag value 0x01 indicates there is error.
                Site.CaptureRequirementIfAreEqual<byte>(
                    0x01,
                    getPropertiesSpecificResponse.RowData.Flag,
                    350,
                    @"[In PidTagAddressBookEntryId Property] This property is set only for public folders.");
            }
            #endregion
        }
        /// <summary>
        /// Get changeNmuber of a specific message object.
        /// </summary>
        /// <param name="serverId">Server id.</param>
        /// <param name="messageId">ID of the message object.</param>
        /// <param name="folderId">ID of the message's parent folder.</param>
        /// <param name="folderHandle">Handle of the message's parent folder</param>
        /// <returns>Change number.</returns>
        private byte[] GetChangeNumber(int serverId, ulong messageId, ulong folderId, uint folderHandle)
        {
            // Open message to get message handle.
            RopOpenMessageRequest openMessageRequest = new RopOpenMessageRequest();
            RopOpenMessageResponse openMessageResponse = new RopOpenMessageResponse();
            openMessageRequest.CodePageId = 0x0fff;
            openMessageRequest.FolderId = folderId;
            openMessageRequest.InputHandleIndex = 0x00;
            openMessageRequest.LogonId = 0x00;
            openMessageRequest.MessageId = messageId;
            openMessageRequest.OpenModeFlags = 0x01;
            openMessageRequest.OutputHandleIndex = 0x01;
            openMessageRequest.RopId = 0x03;
            openMessageResponse = (RopOpenMessageResponse)this.Process(serverId, openMessageRequest, folderHandle);
            uint handle = this.responseSOHs[openMessageResponse.OutputHandleIndex];

            // Get message PidTagChangeKey value.
            RopGetPropertiesSpecificRequest getPropertiesSpecificRequest = new RopGetPropertiesSpecificRequest();
            RopGetPropertiesSpecificResponse getPropertiesSpecificResponse = new RopGetPropertiesSpecificResponse();
            PropertyTag[] propertyTags = new PropertyTag[1];
            PropertyTag tag = new PropertyTag(0x65E2, 0x0102);
            propertyTags[0] = tag;

            getPropertiesSpecificRequest.RopId = 0x07;
            getPropertiesSpecificRequest.LogonId = 0x00;
            getPropertiesSpecificRequest.InputHandleIndex = 0x00;

            // Set PropertySizeLimit, which specifies the maximum size allowed for a property value returned,
            getPropertiesSpecificRequest.PropertySizeLimit = 0xFFFF;
            PropertyTag[] tagArray = propertyTags;
            getPropertiesSpecificRequest.PropertyTagCount = (ushort)tagArray.Length;
            getPropertiesSpecificRequest.PropertyTags = tagArray;

            // Send the RopGetPropertiesSpecific request
            getPropertiesSpecificResponse = (RopGetPropertiesSpecificResponse)this.Process(serverId, getPropertiesSpecificRequest, handle);

            if (getPropertiesSpecificResponse.ReturnValue == 0x0)
            {
                byte[] tempChangeNumber = new byte[getPropertiesSpecificResponse.RowData.PropertyValues[0].Value.Length - 2];
                Array.Copy(getPropertiesSpecificResponse.RowData.PropertyValues[0].Value, 2, tempChangeNumber, 0, getPropertiesSpecificResponse.RowData.PropertyValues[0].Value.Length - 2);
                return tempChangeNumber;
            }
            else
            {
                return new byte[0];
            }
        }
예제 #3
0
        /// <summary>
        /// Verify Common Object properties related requirements.
        /// </summary>
        /// <param name="propertyTag">A property tag both identifies a property and gives the data type its value.</param>
        /// <param name="ropGetPropertiesSecificResponse">The RopGetPropertiesSpecific response buffer structure.</param>
        /// <param name="objectType">Server object type.</param>
        private void VerifyCommonProperties(PropertyTag propertyTag, RopGetPropertiesSpecificResponse ropGetPropertiesSecificResponse, ServerObjectType objectType)
        {
            // Identifies the property
            ushort propertyId = propertyTag.PropertyId;

            foreach (PropertyValue propertyVal in ropGetPropertiesSecificResponse.RowData.PropertyValues)
            {
                // The value of the property. Its syntax is specified by the PropertyType field of the tag, and its semantics by the PropertyId field of the tag, defined in MS-OXCDATA section 2.12.4 TaggedPropertyValue
                uint propertyValue = Common.ConvertByteArrayToUint(propertyVal.Value);

                switch (propertyId)
                {
                    // According to MS-OXPROPS section 2.575 PidTagAccess, if PropertyId is 0x0FF4, it means the property is PidTagAccess.
                    case 0x0FF4:
                        {
                            // Verify MS-OXCPRPT requirement: MS-OXCPRPT_R311
                            // According to MS-OXCDATA section 2.8.1.1 StandardPropertyRow, Flag is equal to 0x00 to Indicates that all property values are present and without error.
                            Site.CaptureRequirementIfAreEqual<uint>(
                                0x00,
                                ropGetPropertiesSecificResponse.RowData.Flag,
                                311,
                                @"[In PidTagAccess Property] Type: PtypInteger32 ([MS-OXCDATA] section 2.11.1)");

                            // Verify MS-OXCPRPT requirement: MS-OXCPRPT_R14
                            int notUsedbits = ~(0x00000001 | 0x00000002 | 0x00000004 | 0x00000008 | 0x00000010 | 0x00000020);
                            bool isVerifyR14 = (propertyValue & notUsedbits) == 0;

                            Site.CaptureRequirementIfIsTrue(
                                isVerifyR14,
                                14,
                                @"[In PidTagAccess Property] The value is a bitwise-OR of zero or more values[0x00000001,0x00000002,0x00000004,0x00000008,0x00000010,0x00000020] from the following table.");
                        }

                        break;

                    // According to MS-OXPROPS 2.577 PidTagAccessLevel, if PropertyId is 0x0FF7, it means the property is PidTagAccessLevel.
                    case 0x0FF7:
                        {
                            // Verify MS-OXCPRPT requirement: MS-OXCPRPT_R312
                            // According to MS-OXCDATA section 2.8.1.1 StandardPropertyRow, Flag is equal to 0x00 to Indicates that all property values are present and without error.
                            Site.CaptureRequirementIfAreEqual<uint>(
                                0x00,
                                ropGetPropertiesSecificResponse.RowData.Flag,
                                312,
                                @"[In PidTagAccessLevel Property] Type: PtypInteger32 ([MS-OXCDATA] section 2.11.1)");

                            // Verify MS-OXCPRPT requirement: MS-OXCPRPT_R26
                            bool isVerifyR26 = (propertyValue == 0x00000000) ||
                                               (propertyValue == 0x00000001);

                            Site.CaptureRequirementIfIsTrue(
                                isVerifyR26,
                                26,
                                @"[In PidTagAccessLevel Property] This value of this property MUST be one of the values in the following table. [0x00000000, 0x00000001].");

                            Site.CaptureRequirementIfAreNotEqual<ServerObjectType>(
                              ServerObjectType.Folder,
                              objectType,
                              2401,
                              @"[In PidTagAccessLevel Property] This property does not apply to Folder objects.");

                            Site.CaptureRequirementIfAreNotEqual<ServerObjectType>(
                                ServerObjectType.Logon,
                                objectType,
                                2402,
                                @"[In PidTagAccessLevel Property] This property does not apply to Logon objects.");
                        }

                        break;

                    // According to MS-OXPROPS 2.701 PidTagChangeKey, if PropertyId is 0x65E2, it means the property is PidTagChangeKey
                    case 0x65E2:
                        {
                            // Verify MS-OXCPRPT requirement: MS-OXCPRPT_R313
                            // According to MS-OXCDATA section 2.8.1.1 StandardPropertyRow, Flag is equal to 0x00 to Indicates that all property values are present and without error.
                            Site.CaptureRequirementIfAreEqual<uint>(
                                0x00,
                                ropGetPropertiesSecificResponse.RowData.Flag,
                                313,
                                @"[In PidTagChangeKey Property] Type: PtypBinary ([MS-OXCDATA] section 2.11.1)");
                        }

                        break;

                    // According to MS-OXPROPS 2.724 PidTagCreationTime, if PropertyId is 0x3007, it means the property is PidTagCreationTime
                    case 0x3007:
                        {
                            // Verify MS-OXCPRPT requirement: MS-OXCPRPT_R314
                            // According to MS-OXCDATA section 2.8.1.1 StandardPropertyRow, Flag is equal to 0x00 to indicate that all property values are present and without error.
                            Site.CaptureRequirementIfAreEqual<uint>(
                                0x00,
                                ropGetPropertiesSecificResponse.RowData.Flag,
                                314,
                                @"[In PidTagCreationTime Property] Type: PtypTime ([MS-OXCDATA] section 2.11.1)");
                        }

                        break;

                    // According to MS-OXPROPS 2.883 PidTagLastModifierName, if PropertyId is 0x3FFA, it means the property is PidTagLastModifierName.
                    case 0x3FFA:
                        {
                            // Verify MS-OXCPRPT requirement: MS-OXCPRPT_R315.
                            // According to MS-OXCDATA section 2.8.1.1 StandardPropertyRow, Flag is equal to 0x00 to indicate that all property values are present and without error.
                            Site.CaptureRequirementIfAreEqual<ushort>(
                                0x00,
                                ropGetPropertiesSecificResponse.RowData.Flag,
                                315,
                                @"[In PidTagLastModifierName Property] Type: PtypString ([MS-OXCDATA] section 2.11.1)");

                            // The property value should be the user who creates the object.
                            string result = Encoding.Unicode.GetString(ropGetPropertiesSecificResponse.RowData.PropertyValues[0].Value).TrimEnd('\0').ToLower();
                            Site.CaptureRequirementIfAreEqual<string>(
                                Common.GetConfigurationPropertyValue("UserName", this.Site).ToLower(),
                                result,
                                34,
                                @"[In PidTagLastModifierName Property] The PidTagLastModifierName property ([MS-OXPROPS] section 2.757) contains the name of the last mail user to modify the object.");

                            Site.CaptureRequirementIfAreNotEqual<ServerObjectType>(
                                 ServerObjectType.Folder,
                                 objectType,
                                 3401,
                                 @"[In PidTagLastModifierName Property] This property does not apply to Folder objects.");

                            Site.CaptureRequirementIfAreNotEqual<ServerObjectType>(
                                ServerObjectType.Logon,
                                objectType,
                                3402,
                                @"[In PidTagLastModifierName Property] This property does not apply to Logon objects.");
                        }

                        break;

                    // According to MS-OXPROPS 2.831 PidTagLastModificationTime, if PropertyId is 0x3008, it means the property is PidTagLastModificationTime.
                    case 0x3008:
                        {
                            // Verify MS-OXCPRPT requirement: MS-OXCPRPT_R316
                            // According to MS-OXCDATA section 2.8.1.1 StandardPropertyRow, Flag is equal to 0x00 to indicate that all property values are present and without error.
                            Site.CaptureRequirementIfAreEqual<uint>(
                                0x00,
                                ropGetPropertiesSecificResponse.RowData.Flag,
                                316,
                                @"[In PidTagLastModificationTimeProperty] Type: PtypTime ([MS-OXCDATA] section 2.11.1)");
                        }

                        break;

                    // According to MS-OXPROPS 2.1059 PidTagSearchKey, if PropertyId is 0x300B, it means the property is PidTagSearchKey
                    case 0x300B:
                        {
                            // Verify MS-OXCPRPT requirement: MS-OXCPRPT_R319
                            // According to MS-OXCDATA section 2.8.1.1 StandardPropertyRow, Flag is equal to 0x00 to indicate that all property values are present and without error.
                            Site.CaptureRequirementIfAreEqual<uint>(
                                0x00,
                                ropGetPropertiesSecificResponse.RowData.Flag,
                                319,
                                @"[In PidTagSearchKey Property] Type: PtypBinary ([MS-OXCDATA] section 2.11.1).");

                            Site.CaptureRequirementIfAreNotEqual<ServerObjectType>(
                                ServerObjectType.Folder,
                                objectType,
                                5501,
                                @"[In PidTagSearchKey Property] This property does not apply to Folder objects.");

                            Site.CaptureRequirementIfAreNotEqual<ServerObjectType>(
                                ServerObjectType.Logon,
                               objectType,
                               5502,
                               @"[In PidTagSearchKey Property] This property does not apply to Logon objects. ");
                        }

                        break;

                    default:
                        break;
                }
            }
        }
        /// <summary>
        /// Override GetPropertyObjFromBuffer with PropertyTag list type.
        /// </summary>
        /// <param name="propertyTags">List of PropertyTag</param>
        /// <param name="response">RopGetPropertiesSpecificResponse packet</param>
        /// <returns>List of PropertyObj</returns>
        public static List<PropertyObj> GetPropertyObjFromBuffer(PropertyTag[] propertyTags, RopGetPropertiesSpecificResponse response)
        {
            List<PropertyObj> propertyList = new List<PropertyObj>();

            for (int i = 0; i < propertyTags.Length; i++)
            {
                PropertyNames propertyName = GetPropertyNameByID(propertyTags[i].PropertyId, propertyTags[i].PropertyType);
                propertyList.Add(GetPropertyObjFromBuffer(new PropertyObj(propertyName), response.RowData.PropertyValues[i].Value));
            }

            return propertyList;
        }
예제 #5
0
        /// <summary>
        /// Verify the RopGetPropertiesSpecific operation related requirements for WantUnicode. 
        /// </summary>
        /// <param name="ropGetPropertiesSpecificResponse">The RopGetPropertiesSpecific response buffer structure.</param>
        /// <param name="isUnicode">Indicates if string properties are to be encoded in the Unicode format in the ROP response buffer.</param>
        private void VerifyRopGetPropertiesSpecificForWantUnicode(RopGetPropertiesSpecificResponse ropGetPropertiesSpecificResponse, bool isUnicode)
        {
            TypedPropertyValue value = (TypedPropertyValue)ropGetPropertiesSpecificResponse.RowData.PropertyValues[0];

            if (isUnicode)
            {
                Site.CaptureRequirementIfAreEqual<ushort>(
                    (ushort)0x001f,
                    value.PropertyType,
                    6401,
                    @"[In RopGetPropertiesSpecific ROP Request Buffer] WantUnicode: A Boolean value that is nonzero if the string properties that are requested with PtypUnspecified ([MS-OXCDATA] section 2.11.1) as the property type are to be encoded in the Unicode format in the ROP response buffer. ");

                Site.CaptureRequirementIfAreEqual<ushort>(
                    (ushort)0x001f,
                    value.PropertyType,
                    458,
                    @"[In Processing RopGetPropertiesSpecific] If the WantUnicode field is set to a nonzero value, the server MUST return string properties that are requested without a specified type (PtypUnspecified) in Unicode format. ");
            }
            else
            {
                Site.CaptureRequirementIfAreEqual<ushort>(
                   (ushort)0x001e,
                   value.PropertyType,
                   65,
                   @"[In RopGetPropertiesSpecific ROP Request Buffer] WantUnicode: If WantUnicode is set to zero, the string properties that are requested with PtypUnspecified as the property type are to be encoded in multibyte character set (MBCS) format.");

                Site.CaptureRequirementIfAreEqual<ushort>(
                   (ushort)0x001e,
                   value.PropertyType,
                   459,
                   @"[In Processing RopGetPropertiesSpecific] If the WantUnicode field is set to zero, the server MUST return string properties that are requested without a specified type (PtypUnspecified) in MBCS format.");
            }

            Site.CaptureRequirementIfAreNotEqual<ushort>(
                (ushort)0x0000,
                value.PropertyType,
                "MS-OXCDATA",
                2720,
                @"[In Property Value Types] PtypUnspecified(PT_UNSPECIFIED) is 
                Any: this property type value matches any type; a server MUST return the actual type in its response. Servers MUST NOT return this type in response to a client request other than NspiGetIDsFromNames or the RopGetPropertyIdsFromNames ROP request ([MS-OXCROPS] section 2.2.8.1). with Property Type Value 0x0000,%x00.00.");
        }
예제 #6
0
        /// <summary>
        /// Verify the RopGetPropertiesSpecific operation related requirements for tagged properties. 
        /// </summary>
        /// <param name="ropGetPropertiesSpecificResponse">The RopGetPropertiesSpecific response buffer structure.</param>
        private void VerifyRopGetPropertiesSpecificForTaggedProperties(RopGetPropertiesSpecificResponse ropGetPropertiesSpecificResponse)
        {
            Site.Assert.AreEqual<int>(3, ropGetPropertiesSpecificResponse.RowData.PropertyValues.Count, "The RopGetPropertiesSpecific operation should return 3 properties.");

            FlaggedPropertyValue firstProperty = ropGetPropertiesSpecificResponse.RowData.PropertyValues[0] as FlaggedPropertyValue;
            Site.Assert.IsNotNull(firstProperty, "The first property returned by the RopGetPropertiesSpecific operation should not be of FlaggedPropertyValue type.");

            // Add the debug information
            Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCPRPT_R457001");

            // Verify MS-OXCPRPT requirement: MS-OXCPRPT_R457001
            // This requirement can be verified since the value (0x0) of flag field in FlaggedPropertyValue means the property value returned from server successfully.
            // The value (0x1) means the PropertyValue field is not present.
            // The value (0xa) means the value is a property error code.
            Site.CaptureRequirementIfAreEqual<byte>(
                0,
                firstProperty.Flag,
                457001,
                @"[In Processing RopGetPropertiesSpecific] The server MUST return the values for the explicitly requested properties on the object, including those set by any client.");

            // The PidTagRecordKey property does not apply to Folder objects and Logon objects.
            if (this.cprptCurrentType == ServerObjectType.Attachment)
            {
                FlaggedPropertyValue secondProperty = ropGetPropertiesSpecificResponse.RowData.PropertyValues[1] as FlaggedPropertyValue;
                Site.Assert.IsNotNull(secondProperty, "The second property returned by the RopGetPropertiesSpecific operation should not be of FlaggedPropertyValue type.");

                // Add the debug information
                Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCPRPT_R457002");

                // Verify MS-OXCPRPT requirement: MS-OXCPRPT_R457002
                // This requirement can be verified since the value (0x0) of flag field in FlaggedPropertyValue means the property value returned from server successfully.
                // The value (0x1) means the PropertyValue field is not present.
                // The value (0xa) means the value is a property error code.
                Site.CaptureRequirementIfAreEqual<byte>(
                    0,
                    secondProperty.Flag,
                    457002,
                    @"[In Processing RopGetPropertiesSpecific] The server MUST return the values for the explicitly requested properties on the object, including those set by any server.");
            }

            // The computation of the value of the PidTagConversationId property is not supported by Exchange 2007.
            if (Common.IsRequirementEnabled(457003, this.Site) && this.cprptCurrentType == ServerObjectType.Message)
            {
                FlaggedPropertyValue thirdProperty = ropGetPropertiesSpecificResponse.RowData.PropertyValues[2] as FlaggedPropertyValue;
                Site.Assert.IsNotNull(thirdProperty, "The third property returned by the RopGetPropertiesSpecific operation should not be of FlaggedPropertyValue type.");

                // Add the debug information
                Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCPRPT_R457003");

                // Verify MS-OXCPRPT requirement: MS-OXCPRPT_R457003
                // This requirement can be verified since the value (0x0) of flag field in FlaggedPropertyValue means the property value returned from server successfully.
                // The value (0x1) means the PropertyValue field is not present.
                // The value (0xa) means the value is a property error code.
                Site.CaptureRequirementIfAreEqual<byte>(
                    0,
                    thirdProperty.Flag,
                    457003,
                    @"[In Processing RopGetPropertiesSpecific] The server MUST return the values for the explicitly requested properties on the object, including those computed properties. ");
            }
        }
예제 #7
0
        /// <summary>
        /// Verify the type of Common Object Properties in MS-OXPROPS.
        /// </summary>
        /// <param name="propertyTag">propertyTag indicates the property currently set on the object.</param>
        /// <param name="ropGetPropertiesSpecificResponse">The RopGetPropertiesSpecific response buffer structure.</param>
        private void VerifyTypeOfCommonPropertiesInOXPROPS(PropertyTag propertyTag, RopGetPropertiesSpecificResponse ropGetPropertiesSpecificResponse)
        {
            switch (propertyTag.PropertyId)
            {
                // According to MS-OXPROPS 2.589 PidTagAccess, if PropertyId is 0x0FF4, it means the property is PidTagAccess
                case 0x0FF4:
                    {
                        // Verify MS-OXPROPS requirement: MS-OXPROPS_R4927
                        // If the property ID is 0x0FF4, it means the associated property is PidTagAccess
                        Site.CaptureRequirement(
                            "MS-OXPROPS",
                            4927,
                            @"[In PidTagAccess] Property ID: 0x0FF4.");

                        // Verify MS-OXPROPS requirement: MS-OXPROPS_R4928
                        // According to MS-OXCDATA section 2.8.1.1 StandardPropertyRow, Flag is equal to 0x00 to indicate that all property values are present and without error.
                        Site.CaptureRequirementIfAreEqual<uint>(
                            0x00,
                            ropGetPropertiesSpecificResponse.RowData.Flag,
                            "MS-OXPROPS",
                            4928,
                            @"[In PidTagAccess] Data type: PtypInteger32, 0x0003.");
                    }

                    break;

                // According to MS-OXPROPS 2.590 PidTagAccessLevel, if PropertyId is 0x0FF7, it means the property is PidTagAccessLevel
                case 0x0FF7:
                    {
                        // Verify MS-OXPROPS requirement: MS-OXPROPS_R4934
                        // If the property ID is 0x0FF7, it means the associated property is PidTagAccessLevel
                        Site.CaptureRequirement(
                            "MS-OXPROPS",
                            4934,
                            @"[In PidTagAccessLevel] Property ID: 0x0FF7.");

                        // Verify MS-OXPROPS requirement: MS-OXPROPS_R4935
                        // According to MS-OXCDATA section 2.8.1.1 StandardPropertyRow, Flag is equal to 0x00 to indicate that all property values are present and without error.
                        Site.CaptureRequirementIfAreEqual<uint>(
                            0x00,
                            ropGetPropertiesSpecificResponse.RowData.Flag,
                            "MS-OXPROPS",
                            4935,
                            @"[In PidTagAccessLevel] Data type: PtypInteger32, 0x0003.");
                    }

                    break;

                // According to MS-OXPROPS 2.700 PidTagChangeKey, if PropertyId is 0x65E2, it means the property is PidTagChangeKey
                case 0x65E2:
                    {
                        // Verify MS-OXPROPS requirement: MS-OXPROPS_R5686
                        // If the property ID is 0x65E2, it means the associated property is PidTagChangeKey
                        Site.CaptureRequirement(
                            "MS-OXPROPS",
                            5686,
                            @"[In PidTagChangeKey] Property ID: 0x65E2.");

                        // Verify MS-OXPROPS requirement: MS-OXPROPS_R5687
                        // According to MS-OXCDATA section 2.8.1.1 StandardPropertyRow, Flag is equal to 0x00 to indicate that all property values are present and without error.
                        Site.CaptureRequirementIfAreEqual<uint>(
                            0x00,
                            ropGetPropertiesSpecificResponse.RowData.Flag,
                            "MS-OXPROPS",
                            5687,
                            @"[In PidTagChangeKey] Data type: PtypBinary, 0x0102.");
                    }

                    break;

                // According to MS-OXPROPS 2.729 PidTagCreationTime, if PropertyId is 0x3007, it means the property is PidTagCreationTime
                case 0x3007:
                    {
                        // Verify MS-OXPROPS requirement: MS-OXPROPS_R5880
                        // If the property ID is 0x3007, it means the associated property is PidTagCreationTime
                        Site.CaptureRequirement(
                            "MS-OXPROPS",
                            5880,
                            @"[In PidTagCreationTime] Property ID: 0x3007.");

                        // Verify MS-OXPROPS requirement: MS-OXPROPS_R5881
                        // According to MS-OXCDATA section 2.8.1.1 StandardPropertyRow, Flag is equal to 0x00 to indicate that all property values are present and without error.
                        Site.CaptureRequirementIfAreEqual<uint>(
                            0x00,
                            ropGetPropertiesSpecificResponse.RowData.Flag,
                            "MS-OXPROPS",
                            5881,
                            @"[In PidTagCreationTime] Data type: PtypTime, 0x0040.");
                    }

                    break;

                // According to MS-OXPROPS 2.868 PidTagLastModifierName, if PropertyId is 0x3FFA, it means the property is PidTagLastModifierName
                case 0x3FFA:
                    {
                        // Verify MS-OXPROPS requirement: MS-OXPROPS_R6796
                        // If the property ID is 0x3FFA, it means the associated property is PidTagLastModifierName
                        Site.CaptureRequirement(
                            "MS-OXPROPS",
                            6796,
                            @"[In PidTagLastModifierName] Property ID: 0x3FFA.");

                        // Verify MS-OXPROPS requirement: MS-OXPROPS_R6797
                        // According to MS-OXCDATA section 2.8.1.1 StandardPropertyRow, Flag is equal to 0x00 to indicate that all property values are present and without error.
                        Site.CaptureRequirementIfAreEqual<uint>(
                            0x00,
                            ropGetPropertiesSpecificResponse.RowData.Flag,
                            "MS-OXPROPS",
                            6797,
                            @"[In PidTagLastModifierName] Data type: PtypString, 0x001F.");
                    }

                    break;

                // According to MS-OXPROPS 2.866 PidTagLastModificationTime, if PropertyId is 0x3008, it means the property is PidTagLastModificationTime
                case 0x3008:
                    {
                        // Verify MS-OXPROPS requirement: MS-OXPROPS_R6783
                        // If the property ID is 0x3008, it means the associated property is PidTagLastModificationTime
                        Site.CaptureRequirement(
                            "MS-OXPROPS",
                            6783,
                            @"[In PidTagLastModificationTime] Property ID: 0x3008.");

                        // Verify MS-OXPROPS requirement: MS-OXPROPS_R6784
                        // According to MS-OXCDATA section 2.8.1.1 StandardPropertyRow, Flag is equal to 0x00 to indicate that all property values are present and without error.
                        Site.CaptureRequirementIfAreEqual<uint>(
                            0x00,
                            ropGetPropertiesSpecificResponse.RowData.Flag,
                            "MS-OXPROPS",
                            6784,
                            @"[In PidTagLastModificationTime] Data type: PtypTime, 0x0040.");
                    }

                    break;

                // According to MS-OXPROPS 2.1110 PidTagSearchKey, if PropertyId is 0x300B, it means the property is PidTagSearchKey
                case 0x300B:
                    {
                        // Verify MS-OXPROPS requirement: MS-OXPROPS_R8385
                        // If the property ID is 0x300B, it means the associated property is PidTagSearchKey
                        Site.CaptureRequirement(
                            "MS-OXPROPS",
                            8385,
                            @"[In PidTagSearchKey] Property ID: 0x300B");

                        // Verify MS-OXPROPS requirement: MS-OXPROPS_R8386
                        // According to MS-OXCDATA section 2.8.1.1 StandardPropertyRow, Flag is equal to 0x00 to indicate that all property values are present and without error.
                        Site.CaptureRequirementIfAreEqual<uint>(
                            0x00,
                            ropGetPropertiesSpecificResponse.RowData.Flag,
                            "MS-OXPROPS",
                            8386,
                            @"[In PidTagSearchKey] Data type: PtypBinary, 0x0102.");
                    }

                    break;
                default:
                    break;
            }
        }
예제 #8
0
        /// <summary>
        /// Verify the Common Properties related requirements in MS-OXCDATA.
        /// </summary>
        /// <param name="propertyTag">A property tag both identifies a property and gives the data type its value.</param>
        /// <param name="ropGetPropertiesSpecificResponse">The RopGetPropertiesSpecific response buffer structure.</param>
        private void VerifyCommonPropertiesInOXCDATA(PropertyTag propertyTag, RopGetPropertiesSpecificResponse ropGetPropertiesSpecificResponse)
        {
            // propertyId indicates the Id of a property.
            ushort propertyId = propertyTag.PropertyId;

            foreach (PropertyValue propertyVal in ropGetPropertiesSpecificResponse.RowData.PropertyValues)
            {
                // PropertyValue (Variable): A PropertyValue structure specifying the value of the property. Its syntax is specified by the PropertyType field of the tag, and its semantics by the PropertyId field of the tag, defined in MS-OXCDATA section 2.12.4 TaggedPropertyValue
                switch (propertyId)
                {
                    // According to MS-OXPROPS 2.700 PidTagChangeKey, if PropertyId is 0x65E2, it means the property is PidTagChangeKey, the Data type is PtypBinary
                    case 0x65E2:
                        {
                            // Verify MS-OXCDATA requirement: MS-OXCDATA_R2707
                            Site.CaptureRequirementIfAreEqual<int>(
                                propertyVal.Value.Length - 2,
                                BitConverter.ToInt16(propertyVal.Value, 0),
                                "MS-OXCDATA",
                                2707,
                                 @"[In Property Data Types] PtypBinary (PT_BINARY) is that variable size; a COUNT field followed by that many bytes with Property Type Value 0x0102,%x02.01.");
                        }

                        break;

                    // According to MS-OXPROPS 2.589 PidTagAccess, if PropertyId is 0x0FF4, it means the property is PidTagAccess, the Data type is PtypInteger32
                    case 0x0FF4:
                        {
                            // Verify MS-OXCDATA requirement: MS-OXCDATA_R2691
                            Site.CaptureRequirementIfAreEqual<int>(
                                4,
                                propertyVal.Value.Length,
                                "MS-OXCDATA",
                                2691,
                                @"[In Property Data Types] PtypInteger32 (PT_LONG, PT_I4, int, ui4) is that 4 bytes; a 32-bit integer [MS-DTYP]: INT32 with Property Type Value 0x0003,%x03.00.");
                        }

                        break;
                    default:
                        break;
                }
            }
        }
예제 #9
0
        /// <summary>
        /// Verify the RopGetPropertiesSpecific operation related requirements.
        /// </summary>
        /// <param name="ropGetPropertiesSpecificResponse">The RopGetPropertiesSpecific response buffer structure.</param>
        /// <param name="objectType">Indicates which object type the RopGetPropertiesSpecific operation is acting on.</param>
        /// <param name="isOrdered">A boolean value which indicates whether the order of elements in request/response buffer is right.</param>
        /// <param name="isPropertySizeLimitZero">Indicates if PropertySizeLimit is set to 0.</param>
        /// <param name="isPropertyLagerThanLimit">Indicates if returned value size is larger than the size limit.</param>
        /// <param name="isValueContainsNotEnoughMemory">Indicates if the value is larger than limit or not.</param>
        private void VerifyRopGetPropertiesSpecific(
            RopGetPropertiesSpecificResponse ropGetPropertiesSpecificResponse,
            ServerObjectType objectType,
            bool isOrdered,
            bool isPropertySizeLimitZero,
            bool isPropertyLagerThanLimit,
            bool isValueContainsNotEnoughMemory)
        {
            // Since the RopGetPropertiesSpecific ROP response was parsed successfully, MS-OXCPRPT_R45602 can be captured directly.
            Site.CaptureRequirement(
                45602,
                @"[In Processing RopGetPropertiesSpecific] The server responds with a RopGetPropertiesSpecific ROP response buffer. ");

            // Verify MS-OXCPRPT requirement: MS-OXCPRPT_R56
            // Since the return value is in order, it verifies the return value is returned in order as the properties specified in the PropertyTags field. So MS-OXCPRPT_R56 can be captured.
            Site.CaptureRequirementIfIsTrue(
                isOrdered,
                56,
                @"[In RopGetPropertiesSpecific ROP] The RopGetPropertiesSpecific ROP ([MS-OXCROPS] section 2.2.8.3) queries for and returns the values of properties specified in the PropertyTags field.");

            // Verify MS-OXCPRPT requirement: MS-OXCPRPT_R45702
            // Since the response for RopGetPropertiesSpecific doesn't contain PropertyTags information, if the returned values for PropertyTags fields in RopGetPropertiesSpecific are same with the setting values in RopSetProperties. 
            // It means the properties to be returned are specified in the PropertyTags field of the request. 
            Site.CaptureRequirementIfIsTrue(
                isOrdered,
                45702,
                @"[In Processing RopGetPropertiesSpecific] The properties to be returned are specified in the PropertyTags field of the ROP request buffer.");

            // The order has been verified when de-serializing the related structures and represented by the variable isOrdered.
            Site.CaptureRequirementIfIsTrue(
               isOrdered,
               "MS-OXCDATA",
               64,
               @"[In PropertyRow Structures] For the RopGetPropertiesSpecific ROP, property values are returned in the order that the properties were requested.");

            // Verify MS-OXCPRPT requirement: MS-OXCPRPT_R45701
            // The order has been verified when de-serializing the related structures and represented by the variable isOrdered.
            Site.CaptureRequirementIfIsTrue(
                isOrdered,
                45701,
                @"[In Processing RopGetPropertiesSpecific] The server MUST order properties in the PropertyValues field of the ROP response buffer in the same order in which properties are specified in the PropertyTags field.");

            // Verify MS-OXCPRPT requirement: MS-OXCPRPT_R76
            // The order has been verified when de-serializing the related structures and represented by the variable isOrdered.
            Site.CaptureRequirementIfIsTrue(
                isOrdered,
                76,
                @"[In RopGetPropertiesSpecific ROP Response Buffer] RowData (variable): A PropertyRow structure ([MS-OXCDATA] section 2.8.1) that contains the values of the properties specified in the ROP request buffer.");

            if (isPropertySizeLimitZero)
            {
                bool isPropertyLimitedByBufferSize = false;
                uint len = 0;
                foreach (PropertyValue value in ropGetPropertiesSpecificResponse.RowData.PropertyValues)
                {
                    len = len + (uint)value.Size();
                }

                isPropertyLimitedByBufferSize = len < uint.MaxValue;

                Site.CaptureRequirementIfIsTrue(
                    isPropertyLimitedByBufferSize,
                    62,
                    @"[In RopGetPropertiesSpecific ROP Request Buffer] PropertySizeLimit: If this value is zero, the property values are limited only by the size of the ROP response buffer. ");
            }

            if (ropGetPropertiesSpecificResponse.ReturnValue.Equals((uint)CPRPTErrorCode.None))
            {
                switch (objectType)
                {
                    case ServerObjectType.Message:
                        
                         // If the object type this operation acting on is Message object and this operation is performed successfully, then the following requirement can be captured.
                        Site.CaptureRequirement(
                            5801,
                            @"[In RopGetPropertiesSpecific ROP] Message objects are supported for this operation [RopGetPropertiesSpecific ROP].");
                        break;
                    case ServerObjectType.Attachment:
                        
                        // If the object type this operation acting on is Attachment object and this operation is performed successfully, then the following requirement can be captured.
                        Site.CaptureRequirement(
                            5803,
                            @"[In RopGetPropertiesSpecific ROP] Attachment objects are supported for this operation [RopGetPropertiesSpecific ROP].");
                        break;
                    case ServerObjectType.Folder:
                        
                        // If the object type this operation acting on is Folder object and this operation is performed successfully, then the following requirement can be captured.
                        Site.CaptureRequirement(
                            5802,
                            @"[In RopGetPropertiesSpecific ROP] Folder objects are supported for this operation [RopGetPropertiesSpecific ROP].");
                        break;
                    case ServerObjectType.Logon:
                        
                        // If the object type this operation acting on is Logon object and this operation is performed successfully, then the following requirement can be captured.
                        Site.CaptureRequirement(
                            5804,
                            @"[In RopGetPropertiesSpecific ROP] Logon objects are supported for this operation [RopGetPropertiesSpecific ROP].");
                        break;
                    default:
                        Site.Assert.Fail("The returned server object type is {0}, which is invalid.", objectType);
                        break;
                }
            }

            if (Common.IsRequirementEnabled(86703, this.Site))
            {
                if (this.cprptCurrentType == ServerObjectType.Message || this.cprptCurrentType == ServerObjectType.Attachment)
                {
                    if (isPropertyLagerThanLimit)
                    {
                        // If MS-OXCPRPT_R86703 is enabled, when the property is a PtypBinary type, a PtypObject type, or a string property, 
                        // the NotEnoughMemory (0x8007000E) will be returned, if the value is larger than either the available space in the ROP response buffer or the size specified in the PropertySizeLimit field of the ROP request buffer.
                        // MS-OXCPRPT_R86703 is captured in model. This requirement is captured here since the requirements from other protocols cannot be handled in model.
                        Site.CaptureRequirementIfIsTrue(
                             isValueContainsNotEnoughMemory,
                             "MS-OXCDATA",
                             2052,
                             @"[In Additional Error Codes] NotEnoughMemory (E_NOMEMORY, MAPI_E_NOT_ENOUGH_MEMORY) will be returned, On get, indicates that the property or column value is too large to be retrieved by the request, and the property value needs to be accessed with the RopOpenStream ROP ([MS-OXCROPS] section 2.2.9.1).");
                    }
                }
            }
        }
        /// <summary>
        /// Verify RopGetPropertiesSpecific Failure Response
        /// </summary>
        /// <param name="ropGetPropertiesSpecificResponse">The failure response of RopGetPropertiesSpecific request</param>
        /// <param name="inputHandleIndex">The field of InputHandleIndex in RopGetPropertiesSpecific request</param>
        private void VerifyRopGetPropertiesSpecificFailureResponse(RopGetPropertiesSpecificResponse ropGetPropertiesSpecificResponse, byte inputHandleIndex)
        {
            // Add the debug information
            Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCROPS_R2705");

            // Verify MS-OXCROPS requirement: MS-OXCROPS_R2705
            Site.CaptureRequirementIfAreEqual<Type>(
                typeof(byte),
                ropGetPropertiesSpecificResponse.RopId.GetType(),
                2705,
                @"[In RopGetPropertiesSpecific ROP Failure Response Buffer]RopId (1 byte): An unsigned integer.");

            // Add the debug information
            Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCROPS_R2707");

            // Verify MS-OXCROPS requirement: MS-OXCROPS_R2707
            Site.CaptureRequirementIfAreEqual<byte>(
                (byte)RopId.RopGetPropertiesSpecific,
                ropGetPropertiesSpecificResponse.RopId,
                2707,
                @"[In RopGetPropertiesSpecific ROP Failure Response Buffer,RopId (1 byte)]For this operation[RopGetPropertiesSpecific], this field is set to 0x07.");

            // Add the debug information
            Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCROPS_R2708");

            // Verify MS-OXCROPS requirement: MS-OXCROPS_R2708
            Site.CaptureRequirementIfAreEqual<Type>(
                typeof(byte),
                ropGetPropertiesSpecificResponse.InputHandleIndex.GetType(),
                2708,
                @"[In RopGetPropertiesSpecific ROP Failure Response Buffer]InputHandleIndex (1 byte): An unsigned integer.");

            // Add the debug information
            Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCROPS_R2709");

            // Verify MS-OXCROPS requirement: MS-OXCROPS_R2709
            Site.CaptureRequirementIfAreEqual<byte>(
                inputHandleIndex,
                ropGetPropertiesSpecificResponse.InputHandleIndex,
                2709,
                @"[In RopGetPropertiesSpecific ROP Failure Response Buffer,InputHandleIndex (1 byte)]This index MUST be set to the value specified in the InputHandleIndex field in the request.");

            // Add the debug information
            Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCROPS_R2711");

            // Verify MS-OXCROPS requirement: MS-OXCROPS_R2711
            Site.CaptureRequirementIfAreEqual<Type>(
                typeof(uint),
                ropGetPropertiesSpecificResponse.ReturnValue.GetType(),
                2711,
                @"[In RopGetPropertiesSpecific ROP Failure Response Buffer]ReturnValue (4 bytes): An unsigned integer.");

            // Add the debug information
            Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCROPS_R2713");

            // Verify MS-OXCROPS requirement: MS-OXCROPS_R2713
            Site.CaptureRequirementIfAreNotEqual<uint>(
                SuccessReturnValue,
                ropGetPropertiesSpecificResponse.ReturnValue,
                2713,
                @"[In RopGetPropertiesSpecific ROP Failure Response Buffer,ReturnValue (4 bytes)]For this response[Failure Response ], this field is set to a value other than 0x00000000.");
        }
        /// <summary>
        /// Verify RopGetPropertiesSpecific Success Response
        /// </summary>
        /// <param name="ropGetPropertiesSpecificResponse">The success response of RopGetPropertiesSpecific request</param>
        /// <param name="inputHandleIndex">The field of InputHandleIndex in RopGetPropertiesSpecific request</param>
        /// <param name="propertyTags">The field of PropertyTags in RopGetPropertiesSpecific request</param>
        private void VerifyRopGetPropertiesSpecificSuccessResponse(RopGetPropertiesSpecificResponse ropGetPropertiesSpecificResponse, byte inputHandleIndex, PropertyTag[] propertyTags)
        {
            // Add the debug information
            Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCROPS_R2693");

            // Verify MS-OXCROPS requirement: MS-OXCROPS_R2693
            Site.CaptureRequirementIfAreEqual<Type>(
                typeof(byte),
                ropGetPropertiesSpecificResponse.RopId.GetType(),
                2693,
                @"[In RopGetPropertiesSpecific ROP Success Response Buffer]RopId (1 byte): An unsigned integer.");

            // Add the debug information
            Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCROPS_R2695");

            // Verify MS-OXCROPS requirement: MS-OXCROPS_R2695
            Site.CaptureRequirementIfAreEqual<byte>(
                (byte)RopId.RopGetPropertiesSpecific,
                ropGetPropertiesSpecificResponse.RopId,
                2695,
                @"[In RopGetPropertiesSpecific ROP Success Response Buffer,RopId (1 byte)]For this operation[RopGetPropertiesSpecific], this field is set to 0x07.");

            // Add the debug information
            Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCROPS_R2696");

            // Verify MS-OXCROPS requirement: MS-OXCROPS_R2696
            Site.CaptureRequirementIfAreEqual<Type>(
                typeof(byte),
                ropGetPropertiesSpecificResponse.InputHandleIndex.GetType(),
                2696,
                @"[In RopGetPropertiesSpecific ROP Success Response Buffer]InputHandleIndex (1 byte): An unsigned integer.");

            // Add the debug information
            Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCROPS_R2697");

            // Verify MS-OXCROPS requirement: MS-OXCROPS_R2697
            Site.CaptureRequirementIfAreEqual<byte>(
                inputHandleIndex,
                ropGetPropertiesSpecificResponse.InputHandleIndex,
                2697,
                @"[In RopGetPropertiesSpecific ROP Success Response Buffer,InputHandleIndex (1 byte)]This index MUST be set to the value specified in the InputHandleIndex field in the request.");

            // Add the debug information
            Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCROPS_R2699");

            // Verify MS-OXCROPS requirement: MS-OXCROPS_R2699
            Site.CaptureRequirementIfAreEqual<Type>(
                typeof(uint),
                ropGetPropertiesSpecificResponse.ReturnValue.GetType(),
                2699,
                @"[In RopGetPropertiesSpecific ROP Success Response Buffer]ReturnValue (4 bytes): An unsigned integer.");

            // Add the debug information
            Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCROPS_R2701");

            // Verify MS-OXCROPS requirement: MS-OXCROPS_R2701
            Site.CaptureRequirementIfAreEqual<uint>(
                SuccessReturnValue,
                ropGetPropertiesSpecificResponse.ReturnValue,
                2701,
                @"[In RopGetPropertiesSpecific ROP Success Response Buffer,ReturnValue (4 bytes)]For this response[Success Response ], this field is set to 0x00000000.");

            // Add the debug information
            Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCROPS_R2702");

            // Verify MS-OXCROPS requirement: MS-OXCROPS_R2702
            Site.CaptureRequirementIfAreEqual<Type>(
                typeof(PropertyRow),
                ropGetPropertiesSpecificResponse.RowData.GetType(),
                2702,
                @"[In RopGetPropertiesSpecific ROP Success Response Buffer]RowData (variable): A PropertyRow structure.");

            // Add the debug information
            Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCROPS_R2704");

            // Verify MS-OXCROPS requirement: MS-OXCROPS_R2704
            Site.CaptureRequirementIfAreEqual<int>(
                propertyTags.Length,
                ropGetPropertiesSpecificResponse.RowData.PropertyValues.Count,
                2704,
                @"[In RopGetPropertiesSpecific ROP Success Response Buffer,RowData (variable)]the columns used for these rows[RowData (variable)] were those specified in the PropertyTags field in the ROP request.");
        }