/// <summary> /// This ROP opens an attachment as a message. /// </summary> /// <param name="handle">The handle to operate.</param> /// <param name="openEmbeddedMessageResponse">The response of this ROP.</param> /// <param name="needVerify">Whether need to verify the response.</param> /// <returns>The index of the output handle of the response.</returns> private uint RopOpenEmbeddedMessage(uint handle, out RopOpenEmbeddedMessageResponse openEmbeddedMessageResponse, bool needVerify) { this.rawDataValue = null; this.responseValue = null; this.responseSOHsValue = null; RopOpenEmbeddedMessageRequest openEmbeddedMessageRequest = new RopOpenEmbeddedMessageRequest() { RopId = (byte)RopId.RopOpenEmbeddedMessage, // The logonId 0x00 is associated with RopOpenEmbeddedMessage. LogonId = 0x00, // This index specifies the location 0x00 in the Server Object Handle Table where the handle for the input Server Object is stored. InputHandleIndex = (byte)HandleIndex.FirstIndex, // This index specifies the location 0x01 in the Server Object Handle Table where the handle for the output Server Object is stored. OutputHandleIndex = (byte)HandleIndex.SecondIndex, CodePageId = 0x0FFF, OpenModeFlags = 0x02 }; this.responseSOHsValue = this.ProcessSingleRop(openEmbeddedMessageRequest, handle, ref this.responseValue, ref this.rawDataValue, RopResponseType.SuccessResponse); openEmbeddedMessageResponse = (RopOpenEmbeddedMessageResponse)this.responseValue; if (needVerify) { this.Site.Assert.AreEqual((uint)RopResponseType.SuccessResponse, openEmbeddedMessageResponse.ReturnValue, string.Format("RopOpenEmbeddedMessage Failed! Error: 0x{0:X8}", openEmbeddedMessageResponse.ReturnValue)); } return(this.responseSOHsValue[0][openEmbeddedMessageResponse.OutputHandleIndex]); }
/// <summary> /// Send ROP request with single operation. /// </summary> /// <param name="ropRequest">ROP request objects.</param> /// <param name="insideObjHandle">Server object handle in request.</param> /// <param name="response">ROP response objects.</param> /// <param name="rawData">The ROP response payload.</param> /// <param name="getPropertiesFlag">The flag indicate the test cases expect to get which object type's properties(message's properties or attachment's properties).</param> /// <param name="returnValue">An unsigned integer value indicates the return value of call EcDoRpcExt2 method.</param> /// <returns>Server objects handles in response.</returns> public List <List <uint> > DoRopCall(ISerializable ropRequest, uint insideObjHandle, ref object response, ref byte[] rawData, GetPropertiesFlags getPropertiesFlag, out uint returnValue) { List <ISerializable> requestRops = new List <ISerializable> { ropRequest }; List <uint> requestSOH = new List <uint> { insideObjHandle }; if (Common.IsOutputHandleInRopRequest(ropRequest)) { // Add an element for server output object handle, set default value to 0xFFFFFFFF requestSOH.Add(DefaultOutputHandle); } List <IDeserializable> responseRops = new List <IDeserializable>(); List <List <uint> > responseSOHs = new List <List <uint> >(); // 0x10008 specifies the maximum size of the rgbOut buffer to place in Response. uint ret = this.oxcropsClient.RopCall(requestRops, requestSOH, ref responseRops, ref responseSOHs, ref rawData, 0x10008); returnValue = ret; if (ret == OxcRpcErrorCode.ECRpcFormat) { this.Site.Assert.Fail("Error RPC Format"); } if (ret != 0) { return(responseSOHs); } if (responseRops != null) { if (responseRops.Count > 0) { response = responseRops[0]; } } else { response = null; } if (ropRequest.GetType() == typeof(RopReleaseRequest)) { return(responseSOHs); } byte ropId = (byte)BitConverter.ToInt16(ropRequest.Serialize(), 0); List <PropertyObj> pts = null; switch (ropId) { case (byte)RopId.RopOpenMessage: RopOpenMessageResponse openMessageResponse = (RopOpenMessageResponse)response; // This check is for the open specification expectation for a particular request with some valid input parameters. if (openMessageResponse.ReturnValue == 0x00000000) { this.VerifyRopOpenMessageResponse(openMessageResponse); } break; case (byte)RopId.RopGetPropertiesSpecific: // RopGetPropertiesSpecificRequest pts = PropertyHelper.GetPropertyObjFromBuffer(((RopGetPropertiesSpecificRequest)ropRequest).PropertyTags, (RopGetPropertiesSpecificResponse)response); foreach (PropertyObj pitem in pts) { // Verify capture code for MS-OXCMSG. this.VerifyMessageSyntaxDataType(pitem); } PropertyObj propertyObjPidTagSubjectPrefix = PropertyHelper.GetPropertyByName(pts, PropertyNames.PidTagSubjectPrefix); PropertyObj propertyObjPidTagNormalizedSubject = PropertyHelper.GetPropertyByName(pts, PropertyNames.PidTagNormalizedSubject); // Verify the message of PidTagSubjectPrefixAndPidTagNormalizedSubject if (PropertyHelper.IsPropertyValid(propertyObjPidTagSubjectPrefix) || PropertyHelper.IsPropertyValid(propertyObjPidTagNormalizedSubject)) { this.VerifyMessageSyntaxPidTagSubjectPrefixAndPidTagNormalizedSubject(propertyObjPidTagSubjectPrefix, propertyObjPidTagNormalizedSubject); } // Verify the requirements of PidTagAttachmentLinkId and PidTagAttachmentFlags. PropertyObj pidTagAttachmentLinkId = PropertyHelper.GetPropertyByName(pts, PropertyNames.PidTagAttachmentLinkId); if (PropertyHelper.IsPropertyValid(pidTagAttachmentLinkId)) { this.VerifyMessageSyntaxPidTagAttachmentLinkIdAndPidTagAttachmentFlags(pidTagAttachmentLinkId); } PropertyObj pidTagAttachmentFlags = PropertyHelper.GetPropertyByName(pts, PropertyNames.PidTagAttachmentFlags); if (PropertyHelper.IsPropertyValid(pidTagAttachmentFlags)) { this.VerifyMessageSyntaxPidTagAttachmentLinkIdAndPidTagAttachmentFlags(pidTagAttachmentFlags); } // Verify the requirements of PidTagDisplayName PropertyObj pidTagDisplayName = PropertyHelper.GetPropertyByName(pts, PropertyNames.PidTagDisplayName); PropertyObj pidTagAttachLongFilename = PropertyHelper.GetPropertyByName(pts, PropertyNames.PidTagAttachLongFilename); if (PropertyHelper.IsPropertyValid(pidTagDisplayName) && PropertyHelper.IsPropertyValid(pidTagAttachLongFilename)) { this.VerifyMessageSyntaxPidTagDisplayName(pidTagDisplayName, pidTagAttachLongFilename); } break; case (byte)RopId.RopGetPropertiesAll: RopGetPropertiesAllResponse getPropertiesAllResponse = (RopGetPropertiesAllResponse)response; pts = PropertyHelper.GetPropertyObjFromBuffer(getPropertiesAllResponse); foreach (PropertyObj pitem in pts) { // Verify capture code for MS-OXCMSG. this.VerifyMessageSyntaxDataType(pitem); } // Verify the requirements of PidTagArchiveDate PropertyObj pidTagArchiveDateObj = PropertyHelper.GetPropertyByName(pts, PropertyNames.PidTagArchiveDate); PropertyObj pidTagStartDateEtc = PropertyHelper.GetPropertyByName(pts, PropertyNames.PidTagStartDateEtc); if (PropertyHelper.IsPropertyValid(pidTagArchiveDateObj)) { if (PropertyHelper.IsPropertyValid(pidTagStartDateEtc)) { byte[] byteDest = new byte[8]; Array.Copy((byte[])pidTagStartDateEtc.Value, 6, byteDest, 0, 8); this.VerifyMessageSyntaxPidTagArchiveDate(pidTagArchiveDateObj, DateTime.FromFileTimeUtc(BitConverter.ToInt64(byteDest, 0))); } } PropertyObj pidTagAccessLevel = PropertyHelper.GetPropertyByName(pts, PropertyNames.PidTagAccessLevel); PropertyObj pidTagRecordKey = PropertyHelper.GetPropertyByName(pts, PropertyNames.PidTagRecordKey); if (getPropertiesFlag == GetPropertiesFlags.MessageProperties) { PropertyObj pidTagAccess = PropertyHelper.GetPropertyByName(pts, PropertyNames.PidTagAccess); PropertyObj pidTagChangeKey = PropertyHelper.GetPropertyByName(pts, PropertyNames.PidTagChangeKey); PropertyObj pidTagCreationTime = PropertyHelper.GetPropertyByName(pts, PropertyNames.PidTagCreationTime); PropertyObj pidTagLastModificationTime = PropertyHelper.GetPropertyByName(pts, PropertyNames.PidTagLastModificationTime); PropertyObj pidTagLastModifierName = PropertyHelper.GetPropertyByName(pts, PropertyNames.PidTagLastModifierName); PropertyObj pidTagSearchKey = PropertyHelper.GetPropertyByName(pts, PropertyNames.PidTagSearchKey); // Verify properties PidTagAccess, PidTagAccessLevel, PidTagChangeKey, PidTagCreationTime, PidTagLastModificationTime, PidTagLastModifierName and PidTagSearchKey exist on all Message objects. this.VerifyPropertiesExistOnAllMessageObject(pidTagAccess, pidTagAccessLevel, pidTagChangeKey, pidTagCreationTime, pidTagLastModificationTime, pidTagLastModifierName, pidTagSearchKey); } if (getPropertiesFlag == GetPropertiesFlags.AttachmentProperties) { // Verify properties PidTagAccessLevel and PidTagRecordKey exist on any Attachment object. this.VerifyPropertiesExistOnAllAttachmentObject(pidTagAccessLevel, pidTagRecordKey); } break; case (byte)RopId.RopCreateMessage: RopCreateMessageResponse createMessageResponse = (RopCreateMessageResponse)response; // Adapter requirements related with RopCreateMessage will be verified if the response is a successful one. if (createMessageResponse.ReturnValue == 0x00000000) { int hasMessageId = createMessageResponse.HasMessageId; this.VerifyMessageSyntaxHasMessageId(hasMessageId); } break; case (byte)RopId.RopReadRecipients: RopReadRecipientsResponse readRecipientsResponse = (RopReadRecipientsResponse)response; // Adapter requirements related with RopReadRecipients will be verified if the response is a successful one. if (readRecipientsResponse.ReturnValue == 0x00000000) { this.VerifyMessageSyntaxRowCount(readRecipientsResponse); } break; case (byte)RopId.RopSetMessageStatus: RopSetMessageStatusResponse setMessageStatusResponse = (RopSetMessageStatusResponse)response; // Adapter requirements related with RopSetMessageStatus will be verified if the response is a successful one. if (setMessageStatusResponse.ReturnValue == 0x00000000) { this.VerifyMessageSyntaxMessageStatusFlags(setMessageStatusResponse); } break; case (byte)RopId.RopCreateAttachment: RopCreateAttachmentResponse createAttachmentResponse = (RopCreateAttachmentResponse)response; // Adapter requirements related with RopCreateAttachment will be verified if the response is a successful one. if (createAttachmentResponse.ReturnValue == 0x00000000) { int id = (int)createAttachmentResponse.AttachmentID; this.VerifyDataStructureRopCreateAttachmentResponse(createAttachmentResponse, id); } break; case (byte)RopId.RopOpenEmbeddedMessage: RopOpenEmbeddedMessageResponse openEmbeddedMessageResponse = (RopOpenEmbeddedMessageResponse)response; // Adapter requirements related with RopOpenEmbeddedMessage will be verified if the response is a successful one. if (openEmbeddedMessageResponse.ReturnValue == 0x00000000) { ulong mid = openEmbeddedMessageResponse.MessageId; this.VerifyDataStructureRopOpenEmbeddedMessageResponse(openEmbeddedMessageResponse, mid); } break; case (byte)RopId.RopSetMessageReadFlag: RopSetMessageReadFlagResponse setMessageReadFlagResponse = (RopSetMessageReadFlagResponse)response; // Adapter requirements related with RopSetMessageReadFlag will be verified if the response is a successful one. if (setMessageReadFlagResponse.ReturnValue == 0x00000000) { this.VerifyMessageSyntaxReadStatusChanged(setMessageReadFlagResponse, (RopSetMessageReadFlagRequest)ropRequest); } break; case (byte)RopId.RopSetReadFlags: // Adapter requirements related with RopSetReadFlags will be verified if the response is a successful one. if (((RopSetReadFlagsResponse)response).ReturnValue == 0x00000000) { this.VerifyRopSetReadFlagsResponse((RopSetReadFlagsResponse)response); } break; case (byte)RopId.RopGetMessageStatus: // Adapter requirements related with RopGetMessageStatus will be verified if the response is a successful one. if (((RopSetMessageStatusResponse)response).ReturnValue == 0x00000000) { this.VerifyGetMessageStatusResponse((RopSetMessageStatusResponse)response); } break; default: break; } this.VerifyMAPITransport(); return(responseSOHs); }
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. (<17> 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_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_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 }