Ejemplo n.º 1
0
        public void MSOXORULE_S04_TC03_ServerExecuteRule_Action_OP_TAG_OnPublicFolder()
        {
            this.CheckMAPIHTTPTransportSupported();

            #region TestUser1 logs on to the public folder.
            RopOpenFolderResponse openFolderResponse;
            RopLogonResponse      logonResponse;
            bool ret = this.OxoruleAdapter.Connect(ConnectionType.PublicFolderServer, this.User1Name, this.User1ESSDN, this.User1Password);
            Site.Assert.IsTrue(ret, "connect to public folder server should be successful");
            uint publicFolderLogonHandler = this.OxoruleAdapter.RopLogon(LogonType.PublicFolder, this.User1ESSDN, out logonResponse);

            // Assert the client to log on to the public folder successfully.
            Site.Assert.AreEqual <uint>(0, logonResponse.ReturnValue, "Logon the public folder should be successful.");

            // Folder index 1 is the Interpersonal Messages subtree, and this is defined in MS-OXCSTOR.
            uint publicfolderHandler = this.OxoruleAdapter.RopOpenFolder(publicFolderLogonHandler, logonResponse.FolderIds[1], out openFolderResponse);

            // Get the store object's entry ID.
            this.GetStoreObjectEntryID(StoreObjectType.PublicFolder, this.Server, this.User1ESSDN);

            RopCreateFolderResponse createFolderResponse;
            string newFolderName   = Common.GenerateResourceName(this.Site, Constants.FolderDisplayName);
            uint   newFolderHandle = this.OxoruleAdapter.RopCreateFolder(publicfolderHandler, newFolderName, Constants.FolderComment, out createFolderResponse);
            ulong  newFolderID     = createFolderResponse.FolderId;
            Site.Assert.AreEqual <uint>(0, createFolderResponse.ReturnValue, "Creating folder operation should succeed.");
            #endregion

            #region TestUser1 prepares value for ruleProperties variable.
            RuleProperties ruleProperties = AdapterHelper.GenerateRuleProperties(this.Site, Constants.RuleNameTag);
            #endregion

            #region TestUser1 adds an OP_TAG rule to the new created folder.
            TagActionData tagActionData            = new TagActionData();
            PropertyTag   tagActionDataPropertyTag = new PropertyTag
            {
                PropertyId   = (ushort)PropertyId.PidTagImportance,
                PropertyType = (ushort)PropertyType.PtypInteger32
            };
            tagActionData.PropertyTag   = tagActionDataPropertyTag;
            tagActionData.PropertyValue = BitConverter.GetBytes(1);

            RuleData ruleOpTag = AdapterHelper.GenerateValidRuleData(ActionType.OP_TAG, TestRuleDataType.ForAdd, 1, RuleState.ST_ENABLED, tagActionData, ruleProperties, null);
            RopModifyRulesResponse modifyRulesResponse = this.OxoruleAdapter.RopModifyRules(newFolderHandle, ModifyRuleFlag.Modify_ReplaceAll, new RuleData[] { ruleOpTag });
            Site.Assert.AreEqual <uint>(0, modifyRulesResponse.ReturnValue, "Adding OP_TAG rule should succeed.");
            #endregion

            #region TestUser1 creates a message.
            RopCreateMessageResponse ropCreateMessageResponse;
            uint messageHandle = this.OxoruleAdapter.RopCreateMessage(newFolderHandle, newFolderID, Convert.ToByte(false), out ropCreateMessageResponse);
            Site.Assert.AreEqual <uint>(0, ropCreateMessageResponse.ReturnValue, "Creating message should succeed.");
            #endregion

            #region TestUser1 saves the subject property of the message to trigger the rule.
            string subjectName = Common.GenerateResourceName(this.Site, ruleProperties.ConditionSubjectName + "Title");
            TaggedPropertyValue subjectProperty          = new TaggedPropertyValue();
            PropertyTag         pidTagSubjectPropertyTag = new PropertyTag
            {
                PropertyId   = (ushort)PropertyId.PidTagSubject,
                PropertyType = (ushort)PropertyType.PtypString
            };
            subjectProperty.PropertyTag = pidTagSubjectPropertyTag;
            subjectProperty.Value       = Encoding.Unicode.GetBytes(subjectName + "\0");

            // Set properties for the created message to trigger the rule.
            RopSetPropertiesResponse ropSetPropertiesResponse = this.OxoruleAdapter.RopSetProperties(messageHandle, new TaggedPropertyValue[] { subjectProperty });
            Site.Assert.AreEqual <uint>(0, ropSetPropertiesResponse.ReturnValue, "Setting property for the created message should succeed.");

            // Save changes of message.
            RopSaveChangesMessageResponse ropSaveChangesMessagResponse = this.OxoruleAdapter.RopSaveChangesMessage(messageHandle);
            Site.Assert.AreEqual <uint>(0, ropSaveChangesMessagResponse.ReturnValue, "Saving the created message should succeed.");

            // Wait for the message to be saved and the rule to take effect.
            Thread.Sleep(this.WaitForTheRuleToTakeEffect);
            #endregion

            #region TestUser1 gets the message and its properties to verify the rule evaluation.
            PropertyTag[] propertyTagList = new PropertyTag[2];
            propertyTagList[0].PropertyId   = (ushort)PropertyId.PidTagImportance;
            propertyTagList[0].PropertyType = (ushort)PropertyType.PtypInteger32;
            propertyTagList[1].PropertyId   = (ushort)PropertyId.PidTagSubject;
            propertyTagList[1].PropertyType = (ushort)PropertyType.PtypString;

            uint contentTableHandle = 0;
            uint rowCount           = 0;
            RopQueryRowsResponse getMailMessageContent = this.GetExpectedMessage(newFolderHandle, ref contentTableHandle, propertyTagList, ref rowCount, 1, subjectName);
            Site.Assert.AreEqual <uint>(1, rowCount, @"The message number in the specific folder should be 1.");
            Site.Assert.AreEqual <int>(1, BitConverter.ToInt32(getMailMessageContent.RowData.PropertyRows[(int)rowCount - 1].PropertyValues[0].Value, 0), "If the rule is executed, the PidTagImportance property of the message should be the value set by the rule.");

            RopDeleteFolderResponse deleteFolder = this.OxoruleAdapter.RopDeleteFolder(publicfolderHandler, newFolderID);
            Site.Assert.AreEqual <uint>(0, deleteFolder.ReturnValue, "Deleting folder should succeed.");
            #endregion
        }
Ejemplo n.º 2
0
        public void MSOXORULE_S04_TC02_AddModifyDeleteExtendedRule_OnPublicFolder()
        {
            this.CheckMAPIHTTPTransportSupported();

            #region TestUser1 logs on to the public folder.
            RopOpenFolderResponse openFolderResponse;
            RopLogonResponse      logonResponse;
            bool ret = this.OxoruleAdapter.Connect(ConnectionType.PublicFolderServer, this.User1Name, this.User1ESSDN, this.User1Password);
            Site.Assert.IsTrue(ret, "connect to public folder server should be successful");
            uint publicFolderLogonHandler = this.OxoruleAdapter.RopLogon(LogonType.PublicFolder, this.User1ESSDN, out logonResponse);

            // Assert the client to log on to the public folder successfully.
            Site.Assert.AreEqual <uint>(0, logonResponse.ReturnValue, "Logon the public folder should be successful.");

            // Folder index 1 is the Interpersonal Messages subtree, and this is defined in MS-OXCSTOR.
            uint publicfolderHandler = this.OxoruleAdapter.RopOpenFolder(publicFolderLogonHandler, logonResponse.FolderIds[1], out openFolderResponse);

            // Get the store object's entry ID.
            this.GetStoreObjectEntryID(StoreObjectType.PublicFolder, this.Server, this.User1ESSDN);

            RopCreateFolderResponse createFolderResponse;
            string newFolderName   = Common.GenerateResourceName(this.Site, Constants.FolderDisplayName);
            uint   newFolderHandle = this.OxoruleAdapter.RopCreateFolder(publicfolderHandler, newFolderName, Constants.FolderComment, out createFolderResponse);
            ulong  newFolderID     = createFolderResponse.FolderId;
            Site.Assert.AreEqual <uint>(0, createFolderResponse.ReturnValue, "Creating folder operation should succeed.");
            #endregion

            #region TestUser1 creates an FAI message.
            RopCreateMessageResponse ropCreateMessageResponse;
            uint extendedRuleMessageHandle = this.OxoruleAdapter.RopCreateMessage(newFolderHandle, newFolderID, Convert.ToByte(true), out ropCreateMessageResponse);
            Site.Assert.AreEqual <uint>(0, ropCreateMessageResponse.ReturnValue, "Creating the first FAI message should succeed.");
            #endregion

            #region TestUser1 adds the extended rule with NamedProperty successfully.
            string            ruleConditionSubjectNameForAdd = Constants.RuleConditionSubjectContainString;
            NamedPropertyInfo namedPropertyInfo = new NamedPropertyInfo
            {
                NoOfNamedProps = 2,
                PropId         = new uint[2]
                {
                    0x8001, 0x8002
                }
            };
            PropertyName testPropertyName = new PropertyName
            {
                Guid = System.Guid.NewGuid().ToByteArray(),
                Kind = 0x01,
                Name = Encoding.Unicode.GetBytes(Constants.NameOfPropertyName + "\0")
            };

            // 0x01 means the property is identified by the name property.
            testPropertyName.NameSize = (byte)testPropertyName.Name.Length;

            PropertyName secondPropertyName = new PropertyName
            {
                Guid = System.Guid.NewGuid().ToByteArray(),
                Kind = 0x00,
                LID  = 0x88888888
            };

            // 0x00 means the property is identified by the LID.
            namedPropertyInfo.NamedProperty = new PropertyName[2] {
                testPropertyName, secondPropertyName
            };
            namedPropertyInfo.NamedPropertiesSize = (uint)(testPropertyName.Serialize().Length + secondPropertyName.Serialize().Length);
            string ruleName = Common.GenerateResourceName(this.Site, Constants.ExtendRulename1);
            TaggedPropertyValue[] extendedRulePropertiesForAdd = AdapterHelper.GenerateExtendedRuleTestData(ruleName, 0, (uint)RuleState.ST_ENABLED, Constants.PidTagRuleProvider, ActionType.OP_MARK_AS_READ, new DeleteMarkReadActionData(), ruleConditionSubjectNameForAdd, namedPropertyInfo);

            // Set properties for extended rule FAI message.
            RopSetPropertiesResponse ropSetPropertiesResponse = this.OxoruleAdapter.RopSetProperties(extendedRuleMessageHandle, extendedRulePropertiesForAdd);
            Site.Assert.AreEqual <uint>(0, ropSetPropertiesResponse.ReturnValue, "Setting property for Extended rule FAI message should succeed.");

            // Save changes of message.
            RopSaveChangesMessageResponse ropSaveChangesMessagResponse = this.OxoruleAdapter.RopSaveChangesMessage(extendedRuleMessageHandle);
            Site.Assert.AreEqual <uint>(0, ropSaveChangesMessagResponse.ReturnValue, "Saving Extend rule message should succeed.");

            // Specify the properties to be got.
            PropertyTag[] propertyTagArray = new PropertyTag[1];

            // PidTagRuleMessageProvider
            propertyTagArray[0].PropertyId   = (ushort)PropertyId.PidTagRuleMessageProvider;
            propertyTagArray[0].PropertyType = (ushort)PropertyType.PtypString;

            // Get the specific properties of the extended rule.
            RopGetPropertiesSpecificResponse ropGetPropertiesSpecificResponse = this.OxoruleAdapter.RopGetPropertiesSpecific(extendedRuleMessageHandle, propertyTagArray);
            Site.Assert.AreEqual <uint>(0, ropGetPropertiesSpecificResponse.ReturnValue, "Getting specific properties operation should succeed.");
            string pidTagRuleMessageProviderData = AdapterHelper.PropertyValueConvertToString(ropGetPropertiesSpecificResponse.RowData.PropertyValues[0].Value);
            Site.Assert.AreEqual <string>(Constants.PidTagRuleProvider, pidTagRuleMessageProviderData, "The rule provider data should be RuleOrganizer.");
            #endregion

            #region Modify the created rule.
            ruleName = Common.GenerateResourceName(this.Site, Constants.ExtendRulename2);
            TaggedPropertyValue[] extendedRulePropertiesForModify = AdapterHelper.GenerateExtendedRuleTestData(ruleName, 0, (uint)RuleState.ST_ENABLED, Constants.PidTagRuleProvider, ActionType.OP_MARK_AS_READ, new DeleteMarkReadActionData(), ruleConditionSubjectNameForAdd, namedPropertyInfo);

            // Set properties for extended rule FAI message.
            ropSetPropertiesResponse = this.OxoruleAdapter.RopSetProperties(extendedRuleMessageHandle, extendedRulePropertiesForModify);
            Site.Assert.AreEqual <uint>(0, ropSetPropertiesResponse.ReturnValue, "Setting property for Extended rule FAI message should succeed.");

            // Save changes of message.
            ropSaveChangesMessagResponse = this.OxoruleAdapter.RopSaveChangesMessage(extendedRuleMessageHandle);
            Site.Assert.AreEqual <uint>(0, ropSaveChangesMessagResponse.ReturnValue, "Saving Extend rule message should succeed.");

            // PidTagSubject
            propertyTagArray[0].PropertyId   = (ushort)PropertyId.PidTagRuleMessageName;
            propertyTagArray[0].PropertyType = (ushort)PropertyType.PtypString;

            // Get the specific properties of the extended rule.
            ropGetPropertiesSpecificResponse = this.OxoruleAdapter.RopGetPropertiesSpecific(extendedRuleMessageHandle, propertyTagArray);
            Site.Assert.AreEqual <uint>(0, ropGetPropertiesSpecificResponse.ReturnValue, "Getting specific properties operation should succeed.");
            string messageName = AdapterHelper.PropertyValueConvertToString(ropGetPropertiesSpecificResponse.RowData.PropertyValues[0].Value);
            Site.Assert.AreEqual <string>(ruleName, messageName, "The rule subject should be {0}.", ruleName);
            #endregion

            #region Release the created message to delete the created rule.
            this.OxoruleAdapter.ReleaseRop(extendedRuleMessageHandle);

            // Get the specific properties of the extended rule.
            ropGetPropertiesSpecificResponse = this.OxoruleAdapter.RopGetPropertiesSpecific(extendedRuleMessageHandle, propertyTagArray);
            Site.Assert.IsNull(ropGetPropertiesSpecificResponse.RowData, "The property value of the extended rule should be null!");
            #endregion

            #region Delete the folder.
            RopDeleteFolderResponse deleteFolder = this.OxoruleAdapter.RopDeleteFolder(publicfolderHandler, newFolderID);
            Site.Assert.AreEqual <uint>(0, deleteFolder.ReturnValue, "Deleting folder should succeed.");
            #endregion
        }
        public void MSOXCMSG_S09_TC03_Transaction()
        {
            this.CheckMapiHttpIsSupported();
            this.ConnectToServer(ConnectionType.PrivateMailboxServer);

            // Set property size
            int size = 0;

            TaggedPropertyValue[] taggedPropertyValueArray = this.CreateMessageTaggedPropertyValueArrays(out size, PidTagAttachMethodFlags.afEmbeddedMessage);

            #region Call RopLogon to log on a mailbox.
            RopLogonResponse logonResponse = this.Logon(LogonType.Mailbox, out this.insideObjHandle);
            #endregion

            #region Call RopCreateMessage to create a message.
            uint targetMessageHandle = this.CreatedMessage(logonResponse.FolderIds[4], this.insideObjHandle);
            #endregion

            #region Call RopSaveChangesMessage to save the newly created message.
            RopSaveChangesMessageResponse saveChangesMessageResponse;
            saveChangesMessageResponse = this.SaveMessage(targetMessageHandle, (byte)SaveFlags.ForceSave);
            #endregion

            #region Call RopOpenMessage to open the message.
            RopOpenMessageResponse openMessageResponse;
            uint openedMessageHandle = this.OpenSpecificMessage(logonResponse.FolderIds[4], saveChangesMessageResponse.MessageId, this.insideObjHandle, MessageOpenModeFlags.ReadWrite, out openMessageResponse);
            Site.Assert.AreEqual <uint>(TestSuiteBase.Success, openMessageResponse.ReturnValue, TestSuiteBase.ROPSucceedMsg);
            #endregion

            #region Call RopCreateAttachment to create an embedded attachment.
            RopCreateAttachmentResponse createAttachmentResponse;
            uint attachmentId;
            uint attachmentHandle = this.CreateAttachment(openedMessageHandle, out createAttachmentResponse, out attachmentId);
            #endregion

            #region Call RopSetProperties to set PidTagAttachMethod property, that is the attachment is the embedded attachment.
            // Setting PidTagAttachMethod property means the attachment is the embedded message
            RopSetPropertiesRequest setPropertiesRequest = new RopSetPropertiesRequest()
            {
                RopId              = (byte)RopId.RopSetProperties,
                LogonId            = CommonLogonId,          // The logonId 0x00 is associated with RopSetProperties.
                InputHandleIndex   = CommonInputHandleIndex, // This index specifies the location 0x00 in the Server Object Handle Table where the handle for the input Server Object is stored.
                PropertyValueSize  = (ushort)(size + 2),
                PropertyValueCount = (ushort)taggedPropertyValueArray.Length,
                PropertyValues     = taggedPropertyValueArray
            };
            this.ResponseSOHs = this.MSOXCMSGAdapter.DoRopCall(setPropertiesRequest, attachmentHandle, ref this.response, ref this.rawData, GetPropertiesFlags.None);
            RopSetPropertiesResponse setPropertiesResponse = (RopSetPropertiesResponse)this.response;
            Site.Assert.AreEqual <uint>(TestSuiteBase.Success, setPropertiesResponse.ReturnValue, TestSuiteBase.ROPSucceedMsg);
            #endregion

            #region Call RopSaveChangesAttachment to save the attachment changes
            RopSaveChangesAttachmentResponse saveChangesAttachmentResponse;
            this.SaveAttachment(attachmentHandle, out saveChangesAttachmentResponse);
            #endregion

            #region Call RopOpenEmbeddedMessage with OpenModeFlags set to 0x02 to create an embedded message.
            RopOpenEmbeddedMessageRequest openEmbeddedMessageRequest = new RopOpenEmbeddedMessageRequest()
            {
                RopId             = (byte)RopId.RopOpenEmbeddedMessage,
                LogonId           = CommonLogonId,           // The logonId 0x00 is associated with RopOpenEmbeddedMessage.
                InputHandleIndex  = CommonInputHandleIndex,  // This index specifies the location 0x00 in the Server Object Handle Table where the handle for the input Server Object is stored.
                OutputHandleIndex = CommonOutputHandleIndex, // This index specifies the location 0x01 in the Server Object Handle Table where the handle for the output Server Object is stored.
                CodePageId        = 0x0FFF,                  // Code page of Logon object is used
                OpenModeFlags     = 0x02                     // Create the attachment if it does not already exist and open the message for both reading and writing
            };
            this.ResponseSOHs = this.MSOXCMSGAdapter.DoRopCall(openEmbeddedMessageRequest, attachmentHandle, ref this.response, ref this.rawData, GetPropertiesFlags.None);
            RopOpenEmbeddedMessageResponse openEmbeddedMessageResponse = (RopOpenEmbeddedMessageResponse)this.response;
            uint embeddedMessageHandle = this.ResponseSOHs[0][openMessageResponse.OutputHandleIndex];
            Site.Assert.AreEqual <uint>(TestSuiteBase.Success, openEmbeddedMessageResponse.ReturnValue, TestSuiteBase.ROPSucceedMsg);
            #endregion

            #region Call RopOpenEmbeddedMessage with OpenModeFlags set to 0x01 to open the embedded message which is created in step 9 and expect a failure response
            RopOpenEmbeddedMessageResponse openEmbeddedMessageResponseFirst;
            openEmbeddedMessageRequest.OpenModeFlags = 0x01; // Try to open the embedded message as read/write.
            this.ResponseSOHs = this.MSOXCMSGAdapter.DoRopCall(openEmbeddedMessageRequest, attachmentHandle, ref this.response, ref this.rawData, GetPropertiesFlags.None);
            openEmbeddedMessageResponseFirst = (RopOpenEmbeddedMessageResponse)this.response;
            #endregion

            #region Call RopSaveChangesMessage to save the embedded message created in step 9.
            saveChangesMessageResponse = this.SaveMessage(embeddedMessageHandle, (byte)SaveFlags.ForceSave);
            #endregion

            #region Call ReleaseRop to release the embedded message created in step 9.
            this.ReleaseRop(embeddedMessageHandle);
            #endregion

            #region Call RopOpenEmbeddedMessage with OpenModeFlags set to 0x01 to open the embedded message which is created in step 9 and expect a successful response.
            RopOpenEmbeddedMessageResponse openEmbeddedMessageResponseSecond;
            openEmbeddedMessageRequest.OpenModeFlags = 0x01; // Try to open the embedded message as read/write.
            this.ResponseSOHs = this.MSOXCMSGAdapter.DoRopCall(openEmbeddedMessageRequest, attachmentHandle, ref this.response, ref this.rawData, GetPropertiesFlags.None);
            openEmbeddedMessageResponseSecond = (RopOpenEmbeddedMessageResponse)this.response;
            #endregion

            // Add the debug information
            this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCMSG_R481. The return value of RopOpenEmbeddedMessage before calling RopSaveChangesMessage is {0}, the return value of RopOpenEmbeddedMessage after calling RopSaveChangesMessage is {1}.", openEmbeddedMessageResponseFirst.ReturnValue, openEmbeddedMessageResponseSecond.ReturnValue);

            // Verify MS-OXCMSG requirement: MS-OXCMSG_R481
            bool isVerifiedR481 = openEmbeddedMessageResponseFirst.ReturnValue != TestSuiteBase.Success && openEmbeddedMessageResponseSecond.ReturnValue == TestSuiteBase.Success;

            // The server doesn't commit the Message object to the containing Attachment object until the RopSaveChangesMessage ROP is called if isVerifiedR481 is true, then MS-OXCMSG_R481 can be verified.
            this.Site.CaptureRequirementIfIsTrue(
                isVerifiedR481,
                481,
                @"[In Receiving a RopOpenEmbeddedMessage ROP Request] The server MUST NOT commit the Message object to the containing Attachment object until the RopSaveChangesMessage ROP ([MS-OXCROPS] section 2.2.6.3) is called with the Embedded Message object's handle.");

            #region Call RopRelease to release the message created in step 2.
            this.ReleaseRop(targetMessageHandle);
            #endregion
        }
        public void MSOXCMSG_S09_TC01_RopOpenEmbeddedMessageSuccessfully()
        {
            this.CheckMapiHttpIsSupported();
            this.ConnectToServer(ConnectionType.PrivateMailboxServer);

            // Set property size
            int size = 0;

            TaggedPropertyValue[] taggedPropertyValueArray = this.CreateMessageTaggedPropertyValueArrays(out size, PidTagAttachMethodFlags.afEmbeddedMessage);

            #region Call RopLogon to log on a mailbox.
            RopLogonResponse logonResponse = this.Logon(LogonType.Mailbox, out this.insideObjHandle);
            #endregion

            #region Call RopCreateMessage to create a message.
            uint targetMessageHandle = this.CreatedMessage(logonResponse.FolderIds[4], this.insideObjHandle);
            #endregion

            #region Call RopCreateAttachment to create an embedded attachment.
            RopCreateAttachmentResponse createAttachmentResponse;
            uint attachmentId;
            uint attachmentHandle = this.CreateAttachment(targetMessageHandle, out createAttachmentResponse, out attachmentId);
            #endregion

            #region Call RopSetProperties to set PidTagAttachMethod property, that is the attachment is the embedded attachment.
            RopSetPropertiesRequest setPropertiesRequest = new RopSetPropertiesRequest()
            {
                RopId              = (byte)RopId.RopSetProperties,
                LogonId            = CommonLogonId,          // The logonId 0x00 is associated with RopSetProperties.
                InputHandleIndex   = CommonInputHandleIndex, // This index specifies the location 0x00 in the Server Object Handle Table where the handle for the input Server Object is stored.
                PropertyValueSize  = (ushort)(size + 2),
                PropertyValueCount = (ushort)taggedPropertyValueArray.Length,
                PropertyValues     = taggedPropertyValueArray
            };
            this.ResponseSOHs = this.MSOXCMSGAdapter.DoRopCall(setPropertiesRequest, attachmentHandle, ref this.response, ref this.rawData, GetPropertiesFlags.None);
            RopSetPropertiesResponse setPropertiesResponse = (RopSetPropertiesResponse)this.response;
            Site.Assert.AreEqual <uint>(TestSuiteBase.Success, setPropertiesResponse.ReturnValue, TestSuiteBase.ROPSucceedMsg);
            #endregion

            #region Call RopGetPropertiesSpecific to get property PidTagAttachMethod of created Attachment
            List <PropertyTag> tagArray = new List <PropertyTag>
            {
                PropertyHelper.PropertyTagDic[PropertyNames.PidTagAttachMethod]
            };

            RopGetPropertiesSpecificResponse getPropertiesSpecificResponse;
            getPropertiesSpecificResponse = this.GetSpecificPropertiesOfMessage(attachmentHandle, tagArray);
            List <PropertyObj> pts = PropertyHelper.GetPropertyObjFromBuffer(tagArray.ToArray(), getPropertiesSpecificResponse);

            // Parse property response get Property Value to verify test  case requirement
            PropertyObj pidTagAttachMethod = PropertyHelper.GetPropertyByName(pts, PropertyNames.PidTagAttachMethod);
            #endregion

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

            // Verify MS-OXCMSG requirement: MS-OXCMSG_R596
            this.Site.CaptureRequirementIfAreEqual <int>(
                0x00000005,
                Convert.ToInt32(pidTagAttachMethod.Value),
                596,
                @"[In PidTagAttachMethod Property] [afEmbeddedMessage (0x00000005)] The attachment is an embedded message that is accessed via the RopOpenEmbeddedMessage ROP ([MS-OXCROPS] section 2.2.6.16).");

            #region Call RopSaveChangesAttachment to save the attachment changes.
            RopSaveChangesAttachmentResponse saveChangesAttachmentResponse;
            this.SaveAttachment(attachmentHandle, out saveChangesAttachmentResponse);
            #endregion

            #region Call RopSaveChangesMessage to save the newly created message.
            RopSaveChangesMessageResponse saveChangesMessageResponse;
            saveChangesMessageResponse = this.SaveMessage(targetMessageHandle, (byte)SaveFlags.ForceSave);
            #endregion

            #region Call RopOpenEmbeddedMessage with OpenModeFlags set to 0x02 to create the attachment if it doesn't exist, and expect to get a successful response
            RopOpenEmbeddedMessageRequest openEmbeddedMessageRequest = new RopOpenEmbeddedMessageRequest()
            {
                RopId             = (byte)RopId.RopOpenEmbeddedMessage,
                LogonId           = CommonLogonId,           // The logonId 0x00 is associated with RopOpenEmbeddedMessage.
                InputHandleIndex  = CommonInputHandleIndex,  // This index specifies the location 0x00 in the Server Object Handle Table where the handle for the input Server Object is stored.
                OutputHandleIndex = CommonOutputHandleIndex, // This index specifies the location 0x01 in the Server Object Handle Table where the handle for the output Server Object is stored.
                CodePageId        = 0x0FFF,                  // Code page of Logon object is used
                OpenModeFlags     = 0x02                     // Create the attachment if it does not already exist and open the message for both reading and writing
            };
            this.ResponseSOHs = this.MSOXCMSGAdapter.DoRopCall(openEmbeddedMessageRequest, attachmentHandle, ref this.response, ref this.rawData, GetPropertiesFlags.None);
            RopOpenEmbeddedMessageResponse openEmbeddedMessageResponse = (RopOpenEmbeddedMessageResponse)this.response;
            Site.Assert.AreEqual <uint>(TestSuiteBase.Success, openEmbeddedMessageResponse.ReturnValue, TestSuiteBase.ROPSucceedMsg);
            uint embeddedMessageHandle = this.ResponseSOHs[0][openEmbeddedMessageResponse.OutputHandleIndex];
            #endregion

            #region Call RopSaveChangesMessage to save the newly created message.
            saveChangesMessageResponse = this.SaveMessage(embeddedMessageHandle, (byte)SaveFlags.ForceSave);
            #endregion

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

            // Verify MS-OXCMSG requirement: MS-OXCMSG_R913
            // The embedded message hasn't been created, so MS-OXCMSG_R913 can be verified if the response of calling RopOpenEmbeddedMessage with OpenModeFlags set to 0x02 is successful.
            this.Site.CaptureRequirementIfAreEqual <uint>(
                TestSuiteBase.Success,
                openEmbeddedMessageResponse.ReturnValue,
                913,
                @"[In RopOpenEmbeddedMessage ROP Request Buffer] [OpenModeFlags] [Create (0x02)] Create the attachment if it does not already exist and open the message for both reading and writing.");

            #region Call RopRelease to release the embedded message
            this.ReleaseRop(embeddedMessageHandle);
            #endregion

            #region Call RopOpenEmbeddedMessage with OpenModeFlags set to 0x00 to open the embedded message as read-only.
            openEmbeddedMessageRequest.CodePageId    = 0x0FFF; // Code page of Logon object is used
            openEmbeddedMessageRequest.OpenModeFlags = 0x00;   // Open the message as read-only.
            this.ResponseSOHs           = this.MSOXCMSGAdapter.DoRopCall(openEmbeddedMessageRequest, attachmentHandle, ref this.response, ref this.rawData, GetPropertiesFlags.None);
            openEmbeddedMessageResponse = (RopOpenEmbeddedMessageResponse)this.response;
            Site.Assert.AreEqual <uint>(TestSuiteBase.Success, openEmbeddedMessageResponse.ReturnValue, TestSuiteBase.ROPSucceedMsg);
            embeddedMessageHandle = this.ResponseSOHs[0][openEmbeddedMessageResponse.OutputHandleIndex];
            #endregion

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

            // Verify MS-OXCMSG requirement: MS-OXCMSG_R881
            // MS-OXCMSG_R881 can be verified when the handle returned from calling RopOpenEmbeddedMessage is not null.
            this.Site.CaptureRequirementIfIsNotNull(
                embeddedMessageHandle,
                881,
                @"[In RopOpenEmbeddedMessage ROP] The RopOpenEmbeddedMessage ROP ([MS-OXCROPS] section 2.2.6.16) retrieves a handle to a Message object from the given Attachment object.");

            #region Call RopModifyRecipients to add recipient to the read-only embedded message and expect to get the failure response
            // Initialize TestUser1
            PropertyTag[]             propertyTag        = this.CreateRecipientColumns();
            List <ModifyRecipientRow> modifyRecipientRow = new List <ModifyRecipientRow>
            {
                this.CreateModifyRecipientRow(TestUser1, 0)
            };

            RopModifyRecipientsResponse modifyRecipientsResponse;
            this.AddRecipients(modifyRecipientRow, embeddedMessageHandle, propertyTag, out modifyRecipientsResponse);
            #endregion

            if (Common.IsRequirementEnabled(3014, this.Site))
            {
                // Add the debug information
                this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCMSG_R3014");

                // Verify MS-OXCMSG requirement: MS-OXCMSG_R3014
                // The response of RopModifyRecipients is not successful because the embedded message is opened as read-only, so MS-OXCMSG_R3014 can be verified.
                this.Site.CaptureRequirementIfAreNotEqual <uint>(
                    TestSuiteBase.Success,
                    modifyRecipientsResponse.ReturnValue,
                    3014,
                    @"[In Appendix A: Product Behavior] [OpenModeFlags] [ReadOnly (0x00)] Message will be opened as read only. (Exchange 2007 follows this behavior.)");
            }

            if (Common.IsRequirementEnabled(3013, this.Site))
            {
                // Add the debug information
                this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCMSG_R3013");

                // Verify MS-OXCMSG requirement: MS-OXCMSG_R3013
                // The response of RopModifyRecipients is successful because the embedded message is opened as read/write, so MS-OXCMSG_R3013 can be verified.
                this.Site.CaptureRequirementIfAreEqual <uint>(
                    TestSuiteBase.Success,
                    modifyRecipientsResponse.ReturnValue,
                    3013,
                    @"[In Appendix A: Product Behavior]  [OpenModeFlags] [ReadOnly (0x00)] Message will be opened as read/write. (&lt;17&gt; Section 2.2.3.16.1:  Exchange 2010, Exchange 2013, Exchange 2016 and Exchange 2019 Preview  follow this behavior.)");
            }

            #region Call RopRelease to release the embedded message.
            this.ReleaseRop(embeddedMessageHandle);
            #endregion

            #region Call RopOpenEmbeddedMessage with OpenModeFlags set to 0x01 to open the embedded message as read/write
            openEmbeddedMessageRequest.InputHandleIndex = 0x00;
            openEmbeddedMessageRequest.OpenModeFlags    = 0x01; // Open the message for both reading and writing.
            this.ResponseSOHs           = this.MSOXCMSGAdapter.DoRopCall(openEmbeddedMessageRequest, attachmentHandle, ref this.response, ref this.rawData, GetPropertiesFlags.None);
            openEmbeddedMessageResponse = (RopOpenEmbeddedMessageResponse)this.response;
            embeddedMessageHandle       = this.ResponseSOHs[0][openEmbeddedMessageResponse.OutputHandleIndex];
            #endregion

            #region Call RopModifyRecipients to add recipient to the read/write embedded message and expect to get the successful response.
            this.AddRecipients(modifyRecipientRow, embeddedMessageHandle, propertyTag, out modifyRecipientsResponse);
            Site.Assert.AreEqual <uint>(TestSuiteBase.Success, modifyRecipientsResponse.ReturnValue, TestSuiteBase.ROPSucceedMsg);
            #endregion

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

            // Verify MS-OXCMSG requirement: MS-OXCMSG_R912
            // The response of RopModifyRecipients is success because the embedded message is opened as read/write, so MS-OXCMSG_R912 can be verified.
            this.Site.CaptureRequirementIfAreEqual <uint>(
                TestSuiteBase.Success,
                modifyRecipientsResponse.ReturnValue,
                912,
                @"[In RopOpenEmbeddedMessage ROP Request Buffer] [OpenModeFlags] [ReadWrite (0x01)] Message will be opened for both reading and writing.");

            #region Call RopRelease to release the created message and the created attachment.
            this.ReleaseRop(embeddedMessageHandle);
            this.ReleaseRop(targetMessageHandle);
            #endregion
        }
        public void MSOXCMSG_S09_TC02_RopOpenEmbeddedMessageFailed()
        {
            this.CheckMapiHttpIsSupported();
            this.ConnectToServer(ConnectionType.PrivateMailboxServer);

            // Set property size
            int size = 0;

            TaggedPropertyValue[] taggedPropertyValueArray = this.CreateMessageTaggedPropertyValueArrays(out size, PidTagAttachMethodFlags.afEmbeddedMessage);

            #region Call RopLogon to log on a mailbox.
            RopLogonResponse logonResponse = this.Logon(LogonType.Mailbox, out this.insideObjHandle);
            #endregion

            #region Call RopCreateMessage to create a message.
            uint targetMessageHandle = this.CreatedMessage(logonResponse.FolderIds[4], this.insideObjHandle);
            #endregion

            #region Call RopSaveChangesMessage to save the newly created message.
            RopSaveChangesMessageResponse saveChangesMessageResponse;
            saveChangesMessageResponse = this.SaveMessage(targetMessageHandle, (byte)SaveFlags.ForceSave);
            #endregion

            #region Call RopOpenMessage to open the message.
            RopOpenMessageResponse openMessageResponse;
            uint openedMessageHandle = this.OpenSpecificMessage(logonResponse.FolderIds[4], saveChangesMessageResponse.MessageId, this.insideObjHandle, MessageOpenModeFlags.ReadWrite, out openMessageResponse);
            Site.Assert.AreEqual <uint>(TestSuiteBase.Success, openMessageResponse.ReturnValue, TestSuiteBase.ROPSucceedMsg);
            #endregion

            #region Call RopCreateAttachment to create an embedded attachment.
            RopCreateAttachmentResponse createAttachmentResponse;
            uint attachmentId;
            uint attachmentHandle = this.CreateAttachment(openedMessageHandle, out createAttachmentResponse, out attachmentId);
            #endregion

            #region Call RopSetProperties to set PidTagAttachMethod property, that is the attachment is the embedded attachment.
            RopSetPropertiesRequest setPropertiesRequest = new RopSetPropertiesRequest()
            {
                RopId              = (byte)RopId.RopSetProperties,
                LogonId            = CommonLogonId,          // The logonId 0x00 is associated with RopSetProperties.
                InputHandleIndex   = CommonInputHandleIndex, // This index specifies the location 0x00 in the Server Object Handle Table where the handle for the input Server Object is stored.
                PropertyValueSize  = (ushort)(size + 2),
                PropertyValueCount = (ushort)taggedPropertyValueArray.Length,
                PropertyValues     = taggedPropertyValueArray
            };
            this.ResponseSOHs = this.MSOXCMSGAdapter.DoRopCall(setPropertiesRequest, attachmentHandle, ref this.response, ref this.rawData, GetPropertiesFlags.None);
            RopSetPropertiesResponse setPropertiesResponse = (RopSetPropertiesResponse)this.response;
            Site.Assert.AreEqual <uint>(TestSuiteBase.Success, setPropertiesResponse.ReturnValue, TestSuiteBase.ROPSucceedMsg);
            #endregion

            #region Call RopSaveChangesAttachment to save the attachment changes.
            RopSaveChangesAttachmentResponse saveChangesAttachmentResponse;
            this.SaveAttachment(attachmentHandle, out saveChangesAttachmentResponse);
            #endregion

            #region Call RopOpenEmbeddedMessage with OpenModeFlags set to 0x02 to create the attachment if it doesn't exist, and expect to get a successful response
            RopOpenEmbeddedMessageRequest openEmbeddedMessageRequest = new RopOpenEmbeddedMessageRequest()
            {
                RopId             = (byte)RopId.RopOpenEmbeddedMessage,
                LogonId           = CommonLogonId,           // The logonId 0x00 is associated with RopOpenEmbeddedMessage.
                InputHandleIndex  = CommonInputHandleIndex,  // This index specifies the location 0x00 in the Server Object Handle Table where the handle for the input Server Object is stored.
                OutputHandleIndex = CommonOutputHandleIndex, // This index specifies the location 0x01 in the Server Object Handle Table where the handle for the output Server Object is stored.
                CodePageId        = 0x0FFF,                  // Code page of Logon object is used
                OpenModeFlags     = 0x02                     // Create the attachment if it does not already exist and open the message for both reading and writing
            };
            this.ResponseSOHs = this.MSOXCMSGAdapter.DoRopCall(openEmbeddedMessageRequest, attachmentHandle, ref this.response, ref this.rawData, GetPropertiesFlags.None);
            RopOpenEmbeddedMessageResponse openEmbeddedMessageResponse = (RopOpenEmbeddedMessageResponse)this.response;
            Site.Assert.AreEqual <uint>(TestSuiteBase.Success, openEmbeddedMessageResponse.ReturnValue, TestSuiteBase.ROPSucceedMsg);
            uint embeddedMessageHandle = this.ResponseSOHs[0][openEmbeddedMessageResponse.OutputHandleIndex];
            #endregion

            #region Call RopRelease to release the embedded message
            this.ReleaseRop(embeddedMessageHandle);
            #endregion

            #region Call RopOpenEmbeddedMessage with CodePageId set to 0x000F and error code 0x000003ef is expected
            openEmbeddedMessageRequest.CodePageId = 0x000F;
            this.ResponseSOHs           = this.MSOXCMSGAdapter.DoRopCall(openEmbeddedMessageRequest, attachmentHandle, ref this.response, ref this.rawData, GetPropertiesFlags.None);
            openEmbeddedMessageResponse = (RopOpenEmbeddedMessageResponse)this.response;
            #endregion

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

            // Verify MS-OXCMSG requirement: MS-OXCMSG_R1068
            this.Site.CaptureRequirementIfAreEqual <uint>(
                0x000003ef,
                openEmbeddedMessageResponse.ReturnValue,
                1068,
                @"[In Receiving a RopOpenEmbeddedMessage ROP Request] [ecUnknownCodePage (0x000003ef)] The code page is unknown.");

            #region Call RopOpenEmbeddedMessage with InputHandleIndex set to 0x01 to open the embedded message and expect to get the error code 0x000004B9 (ecNullObject).
            openEmbeddedMessageRequest.CodePageId       = 0x0FFF; // Code page of Logon object is used
            openEmbeddedMessageRequest.InputHandleIndex = 0x01;
            this.ResponseSOHs           = this.MSOXCMSGAdapter.DoRopCall(openEmbeddedMessageRequest, attachmentHandle, ref this.response, ref this.rawData, GetPropertiesFlags.None);
            openEmbeddedMessageResponse = (RopOpenEmbeddedMessageResponse)this.response;
            #endregion

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

            // Verify MS-OXCMSG requirement: MS-OXCMSG_R1525
            this.Site.CaptureRequirementIfAreEqual <uint>(
                0x000004B9,
                openEmbeddedMessageResponse.ReturnValue,
                1525,
                @"[In Receiving a RopOpenEmbeddedMessage ROP Request] [ecNullObject (0x000004B9)] The value of the InputHandleIndex field on which this ROP [RopOpenEmbeddedMessage] was called does not refer to an Attachment object.");

            #region Call RopRelease to release the embedded message.
            this.ReleaseRop(embeddedMessageHandle);
            this.ReleaseRop(targetMessageHandle);
            #endregion
        }