/// <summary> /// This ROP opens an attachment of a message. /// </summary> /// <param name="handle">The handle to operate.</param> /// <param name="attachmentId">The identifier of the attachment to be opened. </param> /// <param name="openAttachmentResponse">The response of this ROP.</param> /// <param name="needVerify">Whether need to verify the response.</param> /// <returns>The index of the output handle for the response.</returns> private uint RopOpenAttachment(uint handle, uint attachmentId, out RopOpenAttachmentResponse openAttachmentResponse, bool needVerify) { this.rawDataValue = null; this.responseValue = null; this.responseSOHsValue = null; RopOpenAttachmentRequest openAttachmentRequest = new RopOpenAttachmentRequest() { RopId = (byte)RopId.RopOpenAttachment, LogonId = LogonId, InputHandleIndex = (byte)HandleIndex.FirstIndex, OutputHandleIndex = (byte)HandleIndex.SecondIndex, OpenAttachmentFlags = (byte)OpenAttachmentFlags.ReadWrite, AttachmentID = attachmentId }; this.responseSOHsValue = this.ProcessSingleRop(openAttachmentRequest, handle, ref this.responseValue, ref this.rawDataValue, RopResponseType.SuccessResponse); openAttachmentResponse = (RopOpenAttachmentResponse)this.responseValue; if (needVerify) { this.Site.Assert.AreEqual((uint)RopResponseType.SuccessResponse, openAttachmentResponse.ReturnValue, string.Format("RopOpenAttachment Failed! Error: 0x{0:X8}", openAttachmentResponse.ReturnValue)); } return this.responseSOHsValue[0][openAttachmentResponse.OutputHandleIndex]; }
public void MSOXCMSG_S08_TC10_ErrorCodeRelatedWithAttachmentROPs() { this.CheckMapiHttpIsSupported(); this.ConnectToServer(ConnectionType.PrivateMailboxServer); #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 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 with InputHandleIndex set to 0x01 and expect a failure response. RopCreateAttachmentRequest createAttachmentRequest = new RopCreateAttachmentRequest() { RopId = (byte)RopId.RopCreateAttachment, LogonId = CommonLogonId, // The logonId 0x00 is associated with this operation. InputHandleIndex = 0x01, // Set InputHandleIndex to 0x01 which doesn't refer to a Message object. OutputHandleIndex = CommonOutputHandleIndex // This index specifies the location 0x01 in the Server Object Handle Table where the handle for the output Server Object is stored. }; this.ResponseSOHs = this.MSOXCMSGAdapter.DoRopCall(createAttachmentRequest, targetMessageHandle, ref this.response, ref this.rawData, GetPropertiesFlags.None); RopCreateAttachmentResponse createAttachmentResponse = (RopCreateAttachmentResponse)this.response; // Add the debug information this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCMSG_R1712"); // Verify MS-OXCMSG requirement: MS-OXCMSG_R1712 this.Site.CaptureRequirementIfAreEqual<uint>( 0x000004B9, createAttachmentResponse.ReturnValue, 1712, @"[In Receiving a RopCreateAttachment ROP Request] [ecNullObject (0x000004B9)] The value of the InputHandleIndex field on which this ROP [RopCreateAttachment] was called does not refer to a Message object."); #endregion #region Call RopCreateAttachment to create an attachment and expect a successful response. uint attachmentId; uint attachmentHandle = this.CreateAttachment(openedMessageHandle, out createAttachmentResponse, out attachmentId); #endregion #region Call RopSaveChangesAttachment and set the attachmentID to the message ID and expect a failure response. RopSaveChangesAttachmentRequest saveChangesAttachmentRequest = new RopSaveChangesAttachmentRequest() { RopId = (byte)RopId.RopSaveChangesAttachment, LogonId = CommonLogonId, // The logonId 0x00 is associated with this operation. ResponseHandleIndex = CommonOutputHandleIndex, // This index specifies the location in the Server object handle table that is referenced in the response. InputHandleIndex = CommonInputHandleIndex, // This index specifies the location 0x00 in the Server Object Handle Table where the handle for the input Server Object is stored. SaveFlags = (byte)SaveFlags.ForceSave }; this.ResponseSOHs = this.MSOXCMSGAdapter.DoRopCall(saveChangesAttachmentRequest, openedMessageHandle, ref this.response, ref this.rawData, GetPropertiesFlags.None); RopSaveChangesAttachmentResponse saveChangesAttachmentResponse = (RopSaveChangesAttachmentResponse)this.response; Site.Assert.AreNotEqual<uint>(TestSuiteBase.Success, saveChangesAttachmentResponse.ReturnValue, TestSuiteBase.ROPSucceedMsg); // Add the debug information this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCMSG_R467"); // Verify MS-OXCMSG requirement: MS-OXCMSG_R467 this.Site.CaptureRequirementIfAreEqual<uint>( 0x80040102, saveChangesAttachmentResponse.ReturnValue, 467, @"[In Receiving a RopSaveChangesAttachment ROP Request] [ecNotSupported (0x80040102)] The value of the InputHandleIndex field on which this ROP [RopSaveChangesAttachment] was called does not refer to an Attachment object."); #endregion #region Call RopSaveChangesAttachment and set SaveFlags to 0x03 which doesn't specified in the Open Specification and expect a failure response. saveChangesAttachmentRequest.SaveFlags = 0x03; // Set SaveFlags to 0x03 which doesn't specified in the Open Specification this.ResponseSOHs = this.MSOXCMSGAdapter.DoRopCall(saveChangesAttachmentRequest, attachmentHandle, ref this.response, ref this.rawData, GetPropertiesFlags.None); saveChangesAttachmentResponse = (RopSaveChangesAttachmentResponse)this.response; Site.Assert.AreNotEqual<uint>(TestSuiteBase.Success, saveChangesAttachmentResponse.ReturnValue, TestSuiteBase.ROPSucceedMsg); // Add the debug information this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCMSG_R466"); // Verify MS-OXCMSG requirement: MS-OXCMSG_R466 this.Site.CaptureRequirementIfAreEqual<uint>( 0x80040102, saveChangesAttachmentResponse.ReturnValue, 466, @"[In Receiving a RopSaveChangesAttachment ROP Request] [ecNotSupported (0x80040102)] The value of the SaveFlags field is not a supported combination as specified in section 2.2.3.3.1."); #endregion #region Call RopSaveChangesAttachment to save the newly created attachment. this.SaveAttachment(attachmentHandle, out saveChangesAttachmentResponse); #endregion #region Call RopOpenAttachment with InputHandleIndex set to 0x01 which doesn't refer to a message object and expect a failure response RopOpenAttachmentRequest openAttachmentRequest = new RopOpenAttachmentRequest() { RopId = (byte)RopId.RopOpenAttachment, LogonId = CommonLogonId, // The logonId 0x00 is associated with this operation. InputHandleIndex = 0x01, // Set InputHandleIndex to 0x01 which doesn't refer to a Message object. OutputHandleIndex = CommonOutputHandleIndex, // This index specifies the location 0x01 in the Server Object Handle Table where the handle for the output Server Object is stored. OpenAttachmentFlags = 0x01, AttachmentID = attachmentId }; this.ResponseSOHs = this.MSOXCMSGAdapter.DoRopCall(openAttachmentRequest, openedMessageHandle, ref this.response, ref this.rawData, GetPropertiesFlags.None); RopOpenAttachmentResponse openAttachmentResponseFirst = (RopOpenAttachmentResponse)this.response; Site.Assert.AreNotEqual<uint>(TestSuiteBase.Success, openAttachmentResponseFirst.ReturnValue, "The InputHandleIndex is wrong."); // Add the debug information this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCMSG_R1620"); // Verify MS-OXCMSG requirement: MS-OXCMSG_R1620 this.Site.CaptureRequirementIfAreEqual<uint>( 0x000004B9, openAttachmentResponseFirst.ReturnValue, 1620, @"[In Receiving a RopOpenAttachment ROP Request] [ecNullObject (0x000004B9)] The value of the InputHandleIndex field on which this ROP [RopOpenAttachment] was called does not refer to a Message object."); #endregion #region Call RopRelease to release attachment. this.ReleaseRop(attachmentHandle); #endregion #region Call RopGetAttachmentTable with InputHandleIndex set to 0x01 and expect a failure response RopGetAttachmentTableRequest getAttachmentTableRequest = new RopGetAttachmentTableRequest() { RopId = (byte)RopId.RopGetAttachmentTable, LogonId = CommonLogonId, // The logonId 0x00 is associated with this operation. InputHandleIndex = 0x01, // Set InputHandleIndex to 0x01 which doesn't refer to a Message object OutputHandleIndex = CommonOutputHandleIndex, // This index specifies the location 0x01 in the Server Object Handle Table where the handle for the output Server Object is stored. TableFlags = 0x00 // Open the table }; this.ResponseSOHs = this.MSOXCMSGAdapter.DoRopCall(getAttachmentTableRequest, openedMessageHandle, ref this.response, ref this.rawData, GetPropertiesFlags.None); RopGetAttachmentTableResponse getAttachmentTableResponse = (RopGetAttachmentTableResponse)this.response; // Add the debug information this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCMSG_R1526"); // Verify MS-OXCMSG requirement: MS-OXCMSG_R1526 this.Site.CaptureRequirementIfAreEqual<uint>( 0x000004B9, getAttachmentTableResponse.ReturnValue, 1526, @"[In Receiving a RopGetAttachmentTable ROP Request] [ecNullObject (0x000004B9)] The value of the InputHandleIndex field on which this ROP [RopGetAttachmentTable] was called does not refer to a Message object."); #endregion #region Call RopDeleteAttachment and set InputHandleIndex to 0x01 and expect a failure response. RopDeleteAttachmentRequest deleteAttachmentRequest = new RopDeleteAttachmentRequest() { RopId = (byte)RopId.RopDeleteAttachment, LogonId = CommonLogonId, // The logonId 0x00 is associated with this operation. InputHandleIndex = CommonInputHandleIndex, // Set InputHandleIndex to 0x00 which doesn't refer to a Message object. AttachmentID = attachmentId }; // Set InputHandleIndex to 0x00 which doesn't refer to a Message object. this.ResponseSOHs = this.MSOXCMSGAdapter.DoRopCall(deleteAttachmentRequest, TestSuiteBase.InvalidInputHandle, ref this.response, ref this.rawData, GetPropertiesFlags.None); RopDeleteAttachmentResponse deleteAttachmentResponse = (RopDeleteAttachmentResponse)this.response; // Add the debug information this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCMSG_R1524"); // Verify MS-OXCMSG requirement: MS-OXCMSG_R1524 this.Site.CaptureRequirementIfAreEqual<uint>( 0x000004B9, deleteAttachmentResponse.ReturnValue, 1524, @"[In Receiving a RopDeleteAttachment ROP Request] [ecNullObject (0x000004B9)] The value of the InputHandleIndex field on which this ROP [RopDeleteAttachment] was called does not refer to a Message object."); #endregion #region Call RopDeleteAttachment and set AttachmentID to a nonexisting one and expect a failure response. deleteAttachmentRequest.InputHandleIndex = 0x00; deleteAttachmentRequest.AttachmentID = attachmentId + 5; this.ResponseSOHs = this.MSOXCMSGAdapter.DoRopCall(deleteAttachmentRequest, openedMessageHandle, ref this.response, ref this.rawData, GetPropertiesFlags.None); deleteAttachmentResponse = (RopDeleteAttachmentResponse)this.response; // Add the debug information this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCMSG_R1063"); // Verify MS-OXCMSG requirement: MS-OXCMSG_R1063 this.Site.CaptureRequirementIfAreEqual<uint>( 0x8004010F, deleteAttachmentResponse.ReturnValue, 1063, @"[In Receiving a RopDeleteAttachment ROP Request] [ecNotFound (0x8004010F)] The value of the AttachmentID field does not correspond to an attachment on the Message object."); #endregion #region Call RopDeleteAttachment to delete the attachment and expect a successful response. deleteAttachmentRequest.AttachmentID = attachmentId; this.ResponseSOHs = this.MSOXCMSGAdapter.DoRopCall(deleteAttachmentRequest, openedMessageHandle, ref this.response, ref this.rawData, GetPropertiesFlags.None); deleteAttachmentResponse = (RopDeleteAttachmentResponse)this.response; Site.Assert.AreEqual<uint>(TestSuiteBase.Success, deleteAttachmentResponse.ReturnValue, TestSuiteBase.ROPSucceedMsg); #endregion #region Call RopOpenAttachment to open the deleted attachment and expect a failure response. RopOpenAttachmentResponse openAttachmentResponse; this.OpenAttachment(openedMessageHandle, out openAttachmentResponse, attachmentId, OpenAttachmentFlags.ReadWrite); // Add the debug information this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCMSG_R440"); // Verify MS-OXCMSG requirement: MS-OXCMSG_R440 this.Site.CaptureRequirementIfAreEqual<uint>( 0x8004010F, openAttachmentResponse.ReturnValue, 440, @"[In Receiving a RopOpenAttachment ROP Request] [ecNotFound (0x8004010F)] The value of the AttachmentID field does not correspond to an attachment on the Message object."); #endregion #region Call RopRelease to release the created message and attachment. this.ReleaseRop(attachmentHandle); this.ReleaseRop(targetMessageHandle); #endregion }
/// <summary> /// Open the attachment /// </summary> /// <param name="objectHandle">A Server object handle.</param> /// <param name="openAttachmentResponse">The RopOpenAttachmentResponse value.</param> /// <param name="attachmentId">The ID of an attachment to be opened.</param> /// <param name="openFlags">The OpenModeFlags value.</param> /// <returns>A Server object handle of the opened attachment.</returns> private uint OpenAttachment(uint objectHandle, out RopOpenAttachmentResponse openAttachmentResponse, uint attachmentId, OpenAttachmentFlags openFlags) { RopOpenAttachmentRequest openAttachmentRequest = new RopOpenAttachmentRequest() { RopId = (byte)RopId.RopOpenAttachment, LogonId = CommonLogonId, // The logonId 0x00 is associated with this operation. 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. OpenAttachmentFlags = (byte)openFlags, AttachmentID = attachmentId }; this.ResponseSOHs = this.MSOXCMSGAdapter.DoRopCall(openAttachmentRequest, objectHandle, ref this.response, ref this.rawData, GetPropertiesFlags.None); openAttachmentResponse = (RopOpenAttachmentResponse)this.response; return this.ResponseSOHs[0][openAttachmentResponse.OutputHandleIndex]; }
public void MSOXCMSG_S08_TC01_RopCreateOpenSaveAttachmentSuccessfully() { this.CheckMapiHttpIsSupported(); this.ConnectToServer(ConnectionType.PrivateMailboxServer); #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 message RopSaveChangesMessageResponse saveChangesMessageResponse; saveChangesMessageResponse = this.SaveMessage(targetMessageHandle, (byte)SaveFlags.ForceSave); Site.Assert.AreEqual<uint>(TestSuiteBase.Success, saveChangesMessageResponse.ReturnValue, TestSuiteBase.ROPSucceedMsg); #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 attachment and expect a successful response. RopCreateAttachmentResponse createAttachmentResponse; uint attachmentId; uint attachmentHandle = this.CreateAttachment(openedMessageHandle, out createAttachmentResponse, out attachmentId); #endregion #region Call RopSaveChangesAttachment to save the newly created attachment. RopSaveChangesAttachmentResponse saveChangesAttachmentResponse; this.SaveAttachment(attachmentHandle, out saveChangesAttachmentResponse); #endregion #region Call RopOpenAttachment with InputHandleIndex set to 0x01 which doesn't refer to a message object and expect a failure response RopOpenAttachmentRequest openAttachmentRequest = new RopOpenAttachmentRequest() { RopId = (byte)RopId.RopOpenAttachment, LogonId = CommonLogonId, // The logonId 0x00 is associated with this operation. InputHandleIndex = 0x01, // Set InputHandleIndex to 0x01 which doesn't refer to a Message object. OutputHandleIndex = CommonOutputHandleIndex, // This index specifies the location 0x01 in the Server Object Handle Table where the handle for the output Server Object is stored. OpenAttachmentFlags = 0x01, AttachmentID = attachmentId }; this.ResponseSOHs = this.MSOXCMSGAdapter.DoRopCall(openAttachmentRequest, openedMessageHandle, ref this.response, ref this.rawData, GetPropertiesFlags.None); RopOpenAttachmentResponse openAttachmentResponseFirst = (RopOpenAttachmentResponse)this.response; Site.Assert.AreNotEqual<uint>(TestSuiteBase.Success, openAttachmentResponseFirst.ReturnValue, "The InputHandleIndex is wrong."); #endregion #region Call RopOpenAttachment to open the attachment as read/write and expect a successful response. RopOpenAttachmentResponse openAttachmentResponseSecond; uint openedAttachmentHandle = this.OpenAttachment(openedMessageHandle, out openAttachmentResponseSecond, attachmentId, OpenAttachmentFlags.ReadWrite); Site.Assert.AreEqual<uint>(TestSuiteBase.Success, openAttachmentResponseSecond.ReturnValue, TestSuiteBase.ROPSucceedMsg); // Add the debug information this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCMSG_R446. The return value of RopOpenAttachmentRequest before saving the attachment is {0}, the return value of RopOpenAttachmentRequest after saving the attachment is {1}.", openAttachmentResponseFirst.ReturnValue, openAttachmentResponseSecond.ReturnValue); // Verify MS-OXCMSG requirement: MS-OXCMSG_R446 bool isVerifiedR446 = openAttachmentResponseFirst.ReturnValue != TestSuiteBase.Success && openAttachmentResponseSecond.ReturnValue == TestSuiteBase.Success; this.Site.CaptureRequirementIfIsTrue( isVerifiedR446, 446, @"[In Receiving a RopCreateAttachment ROP Request] When processing the RopCreateAttachment ROP ([MS-OXCROPS] section 2.2.6.13), the server does not commit the new Attachment object until it receives a call to the RopSaveChangesAttachment ROP ([MS-OXCROPS] section 2.2.6.15)."); // Add the debug information this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCMSG_R853"); // Verify MS-OXCMSG requirement: MS-OXCMSG_R853 this.Site.CaptureRequirementIfAreEqual<uint>( TestSuiteBase.Success, openAttachmentResponseSecond.ReturnValue, 853, @"[In RopOpenAttachment ROP] The RopOpenAttachment ROP ([MS-OXCROPS] section 2.2.6.12) opens an Attachment object stored on the Message object."); // Add the debug information this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCMSG_R861"); // Verify MS-OXCMSG requirement: MS-OXCMSG_R861 this.Site.CaptureRequirementIfAreEqual<uint>( TestSuiteBase.Success, openAttachmentResponseSecond.ReturnValue, 861, @"[In RopCreateAttachment ROP] The RopCreateAttachment ROP ([MS-OXCROPS] section 2.2.6.13) creates a new Attachment object on the Message object."); #endregion #region Call RopSetProperties to set the displayname of the attachment and expect a successful response. List<PropertyObj> lstPts = new List<PropertyObj> { new PropertyObj(PropertyNames.PidTagDisplayName, Common.GetBytesFromUnicodeString("Test")) }; RopSetPropertiesResponse setPropertiesResponse; this.SetPropertiesForMessage(openedAttachmentHandle, lstPts, out setPropertiesResponse); // Add the debug information this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCMSG_R918"); // Verify MS-OXCMSG requirement: MS-OXCMSG_R918 // The calling RopSetPropertiesRequest succeeds indicates that the opened attachment can be modified, so MS-OXCMSG_R918 can be verified. this.Site.CaptureRequirementIfAreEqual<uint>( TestSuiteBase.Success, setPropertiesResponse.ReturnValue, 918, @"[In RopOpenAttachment ROP Request Buffer] [OpenAttachmentFlags] [ReadWrite (0x01)] Attachment will be opened for both reading and writing."); #endregion #region Call RopSaveChangesAttachment and set SaveFlags to 0x0C and expect a successful response. this.SaveAttachment(openedAttachmentHandle, out saveChangesAttachmentResponse); #endregion #region Call RopOpenAttachment to open the attachment as BestAccess and expect a successful response. RopOpenAttachmentResponse openAttachmentResponseForBestAccess; openedAttachmentHandle = this.OpenAttachment(openedMessageHandle, out openAttachmentResponseForBestAccess, attachmentId, OpenAttachmentFlags.BestAccess); Site.Assert.AreEqual<uint>(TestSuiteBase.Success, openAttachmentResponseSecond.ReturnValue, TestSuiteBase.ROPSucceedMsg); #endregion #region Call RopSetProperties to set the displayname of the attachment and expect a successful response. lstPts = new List<PropertyObj> { new PropertyObj(PropertyNames.PidTagDisplayName, Common.GetBytesFromUnicodeString("TestForBestAccess")) }; this.SetPropertiesForMessage(openedAttachmentHandle, lstPts, out setPropertiesResponse); // Add the debug information this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCMSG_R919"); // Verify MS-OXCMSG requirement: MS-OXCMSG_R919 // Because the user is onwer of the mailbox, so the user has write permissions for the attachment. // The calling RopSetPropertiesRequest succeeds indicates that the opened attachment can be modified, so MS-OXCMSG_R919 can be verified. this.Site.CaptureRequirementIfAreEqual<uint>( TestSuiteBase.Success, setPropertiesResponse.ReturnValue, 919, @"[In RopOpenAttachment ROP Request Buffer] [OpenAttachmentFlags] [BestAccess (0x03)] Attachment will be opened for read/write if the user has write permissions for the attachment; opened for read-only if not."); #endregion #region Call RopRelease to release the created message. this.ReleaseRop(openedMessageHandle); #endregion }