/// <summary> /// Open a specified message in specified folder. /// </summary> /// <param name="messageId">The specified message ID.</param> /// <param name="folderId">The specified folder ID.</param> /// <param name="openModeFlags">OpenModeFlags for RopOpenMessage.</param> /// <returns>The response of RopOpenMessage ROP operation.</returns> protected RopOpenMessageResponse OpenMessage(ulong messageId, ulong folderId, MessageOpenModeFlags openModeFlags) { RopOpenFolderRequest openFolderRequest = new RopOpenFolderRequest { RopId = (byte)RopId.RopOpenFolder, LogonId = Constants.CommonLogonId, InputHandleIndex = Constants.CommonInputHandleIndex, OutputHandleIndex = Constants.CommonOutputHandleIndex, OpenModeFlags = (byte)FolderOpenModeFlags.None, FolderId = folderId }; RopOpenFolderResponse openFolderResponse = this.Adapter.OpenFolder(openFolderRequest, this.LogonHandle, ref this.responseHandles); uint folderHandle = this.responseHandles[0][openFolderResponse.OutputHandleIndex]; RopOpenMessageRequest openMessageRequest = new RopOpenMessageRequest(); object ropResponse = null; openMessageRequest.RopId = (byte)RopId.RopOpenMessage; openMessageRequest.LogonId = Constants.CommonLogonId; openMessageRequest.InputHandleIndex = Constants.CommonInputHandleIndex; openMessageRequest.OutputHandleIndex = Constants.CommonOutputHandleIndex; openMessageRequest.OpenModeFlags = (byte)openModeFlags; openMessageRequest.FolderId = folderId; openMessageRequest.MessageId = messageId; openMessageRequest.CodePageId = 0x0fff; this.Adapter.DoRopCall(openMessageRequest, folderHandle, ref ropResponse, ref this.responseHandles); return (RopOpenMessageResponse)ropResponse; }
/// <summary> /// This ROP opens an existing message in a mailbox. /// </summary> /// <param name="handle">The handle to operate</param> /// <param name="folderId">The parent folder of the message to be opened.</param> /// <param name="messageId">The identifier of the message to be opened.</param> /// <param name="openMessageResponse">The response of this ROP.</param> /// <param name="needVerify">Whether need to verify the response</param> /// <returns>The handle of the opened message</returns> private uint RopOpenMessage(uint handle, ulong folderId, ulong messageId, out RopOpenMessageResponse openMessageResponse, bool needVerify) { this.rawDataValue = null; this.responseValue = null; this.responseSOHsValue = null; RopOpenMessageRequest openMessageRequest = new RopOpenMessageRequest() { RopId = (byte)RopId.RopOpenMessage, LogonId = LogonId, InputHandleIndex = (byte)HandleIndex.FirstIndex, OutputHandleIndex = (byte)HandleIndex.SecondIndex, // Set CodePageId to SameAsLogonObject, which indicates it uses the same code page as the one for logon object. CodePageId = (ushort)CodePageId.SameAsLogonObject, FolderId = folderId, // Set OpenModeFlags to read and write for further operation. OpenModeFlags = (byte)MessageOpenModeFlags.ReadWrite, MessageId = messageId }; this.responseSOHsValue = this.ProcessSingleRop(openMessageRequest, handle, ref this.responseValue, ref this.rawDataValue, RopResponseType.SuccessResponse); openMessageResponse = (RopOpenMessageResponse)this.responseValue; if (needVerify) { this.Site.Assert.AreEqual((uint)RopResponseType.SuccessResponse, openMessageResponse.ReturnValue, string.Format("RopOpenMessageResponse Failed! Error: 0x{0:X8}", openMessageResponse.ReturnValue)); } return this.responseSOHsValue[0][openMessageResponse.OutputHandleIndex]; }
/// <summary> /// Get changeNmuber of a specific message object. /// </summary> /// <param name="serverId">Server id.</param> /// <param name="messageId">ID of the message object.</param> /// <param name="folderId">ID of the message's parent folder.</param> /// <param name="folderHandle">Handle of the message's parent folder</param> /// <returns>Change number.</returns> private byte[] GetChangeNumber(int serverId, ulong messageId, ulong folderId, uint folderHandle) { // Open message to get message handle. RopOpenMessageRequest openMessageRequest = new RopOpenMessageRequest(); RopOpenMessageResponse openMessageResponse = new RopOpenMessageResponse(); openMessageRequest.CodePageId = 0x0fff; openMessageRequest.FolderId = folderId; openMessageRequest.InputHandleIndex = 0x00; openMessageRequest.LogonId = 0x00; openMessageRequest.MessageId = messageId; openMessageRequest.OpenModeFlags = 0x01; openMessageRequest.OutputHandleIndex = 0x01; openMessageRequest.RopId = 0x03; openMessageResponse = (RopOpenMessageResponse)this.Process(serverId, openMessageRequest, folderHandle); uint handle = this.responseSOHs[openMessageResponse.OutputHandleIndex]; // Get message PidTagChangeKey value. RopGetPropertiesSpecificRequest getPropertiesSpecificRequest = new RopGetPropertiesSpecificRequest(); RopGetPropertiesSpecificResponse getPropertiesSpecificResponse = new RopGetPropertiesSpecificResponse(); PropertyTag[] propertyTags = new PropertyTag[1]; PropertyTag tag = new PropertyTag(0x65E2, 0x0102); propertyTags[0] = tag; getPropertiesSpecificRequest.RopId = 0x07; getPropertiesSpecificRequest.LogonId = 0x00; getPropertiesSpecificRequest.InputHandleIndex = 0x00; // Set PropertySizeLimit, which specifies the maximum size allowed for a property value returned, getPropertiesSpecificRequest.PropertySizeLimit = 0xFFFF; PropertyTag[] tagArray = propertyTags; getPropertiesSpecificRequest.PropertyTagCount = (ushort)tagArray.Length; getPropertiesSpecificRequest.PropertyTags = tagArray; // Send the RopGetPropertiesSpecific request getPropertiesSpecificResponse = (RopGetPropertiesSpecificResponse)this.Process(serverId, getPropertiesSpecificRequest, handle); if (getPropertiesSpecificResponse.ReturnValue == 0x0) { byte[] tempChangeNumber = new byte[getPropertiesSpecificResponse.RowData.PropertyValues[0].Value.Length - 2]; Array.Copy(getPropertiesSpecificResponse.RowData.PropertyValues[0].Value, 2, tempChangeNumber, 0, getPropertiesSpecificResponse.RowData.PropertyValues[0].Value.Length - 2); return tempChangeNumber; } else { return new byte[0]; } }
public void MSOXCMSG_S01_TC01_RopCreateMessageAndRopSaveChangesMessage() { this.CheckMapiHttpIsSupported(); this.ConnectToServer(ConnectionType.PrivateMailboxServer); #region Call RopLogon to log on a private mailbox. RopLogonResponse logonResponse = this.Logon(LogonType.Mailbox, out this.insideObjHandle); #endregion #region Call RopOpenFolder to open inbox folder uint openedFolderHandle = this.OpenSpecificFolder(logonResponse.FolderIds[4], this.insideObjHandle); #endregion #region Call RopGetContentsTable to get the contents table of inbox folder before create message. RopGetContentsTableRequest getContentsTableRequest = new RopGetContentsTableRequest() { RopId = (byte)RopId.RopGetContentsTable, LogonId = CommonLogonId, InputHandleIndex = CommonInputHandleIndex, OutputHandleIndex = CommonOutputHandleIndex, TableFlags = (byte)FolderTableFlags.None }; this.ResponseSOHs = this.MSOXCMSGAdapter.DoRopCall(getContentsTableRequest, openedFolderHandle, ref this.response, ref this.rawData, GetPropertiesFlags.None); RopGetContentsTableResponse getContentsTableResponse = (RopGetContentsTableResponse)this.response; Site.Assert.AreEqual<uint>(TestSuiteBase.Success, getContentsTableResponse.ReturnValue, "Call RopGetContentsTable should success."); uint rowCount = getContentsTableResponse.RowCount; #endregion #region Call RopCreateMessage to create new not FAI Message object. RopCreateMessageRequest createMessageRequest = new RopCreateMessageRequest() { RopId = (byte)RopId.RopCreateMessage, LogonId = CommonLogonId, InputHandleIndex = CommonInputHandleIndex, OutputHandleIndex = CommonOutputHandleIndex, CodePageId = 0x0FFF, // Code page of Logon object is used FolderId = logonResponse.FolderIds[4], // Create a message in INBOX which root is mailbox AssociatedFlag = 0x00 // NOT an FAI message }; this.ResponseSOHs = this.MSOXCMSGAdapter.DoRopCall(createMessageRequest, this.insideObjHandle, ref this.response, ref this.rawData, GetPropertiesFlags.None); RopCreateMessageResponse createMessageResponse = (RopCreateMessageResponse)this.response; Site.Assert.AreEqual<uint>(TestSuiteBase.Success, createMessageResponse.ReturnValue, "Call RopCreateMessage should success."); uint targetMessageHandle = this.ResponseSOHs[0][createMessageResponse.OutputHandleIndex]; // Add the debug information this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCMSG_R991, The HasMessageId field is {0}", createMessageResponse.HasMessageId); // Verify MS-OXCMSG requirement: MS-OXCMSG_R991 bool isVerifiedR991 = createMessageResponse.HasMessageId == 0x00 && createMessageResponse.MessageId == null; this.Site.CaptureRequirementIfIsTrue( isVerifiedR991, 991, @"[In RopCreateMessage ROP Response Buffer] [HasMessageId] The value 0x00 means this is the last byte in the buffer."); #endregion #region Call RopGetContentsTable to get the contents table of inbox folder before save message. this.ResponseSOHs = this.MSOXCMSGAdapter.DoRopCall(getContentsTableRequest, openedFolderHandle, ref this.response, ref this.rawData, GetPropertiesFlags.None); getContentsTableResponse = (RopGetContentsTableResponse)this.response; Site.Assert.AreEqual<uint>(TestSuiteBase.Success, createMessageResponse.ReturnValue, "Call RopGetContents should success."); // Add the debug information this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCMSG_R339"); // Verify MS-OXCMSG requirement: MS-OXCMSG_R339 this.Site.CaptureRequirementIfAreEqual<uint>( rowCount, getContentsTableResponse.RowCount, 339, @"[In Receiving a RopCreateMessage ROP Request] When processing the RopCreateMessage ROP ([MS-OXCROPS] section 2.2.6.2), the server MUST NOT commit the new Message object until it [server] receives a RopSaveChangesMessage ROP request ([MS-OXCROPS] section 2.2.6.3)."); #endregion #region Call RopSaveChangesMessage to commit the Message object created. RopSaveChangesMessageResponse saveChangesMessageResponse = this.SaveMessage(targetMessageHandle, (byte)SaveFlags.ForceSave); Site.Assert.AreEqual<uint>(TestSuiteBase.Success, saveChangesMessageResponse.ReturnValue, TestSuiteBase.ROPSucceedMsg); // Add the debug information this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCMSG_R728"); // Verify MS-OXCMSG requirement: MS-OXCMSG_R728 this.Site.CaptureRequirementIfAreEqual<int>( 8, BitConverter.GetBytes(saveChangesMessageResponse.MessageId).Length, 728, @"[In RopSaveChangesMessage ROP Response Buffer] Message Id: 8 bytes containing the MID ([MS-OXCDATA] section 2.2.1.2) for the saved Message object."); // Add the debug information this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCMSG_R372, the MID in RopSaveChangesMessage Response is {0}.", saveChangesMessageResponse.MessageId); // Verify MS-OXCMSG requirement: MS-OXCMSG_R372 // Because the R728 verify the RopSaveChangesMessage ROP response contains a MID and it's length is 8 bytes. // So R372 will be verified directly. this.Site.CaptureRequirement( 372, @"[In Receiving a RopSaveChangesMessage ROP Request] The response contains the MID ([MS-OXCDATA] section 2.2.1.2) of the committed message."); #endregion #region Call RopGetContentsTable to get the contents table of inbox folder after save message. this.ResponseSOHs = this.MSOXCMSGAdapter.DoRopCall(getContentsTableRequest, openedFolderHandle, ref this.response, ref this.rawData, GetPropertiesFlags.None); getContentsTableResponse = (RopGetContentsTableResponse)this.response; Site.Assert.AreEqual<uint>(TestSuiteBase.Success, createMessageResponse.ReturnValue, "Call RopGetContents should success."); uint contentTableHandle = this.ResponseSOHs[0][getContentsTableResponse.OutputHandleIndex]; #region Verify MS-OXCMSG_R700, MS-OXCMSG_R687 // Add the debug information this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCMSG_R687"); // Verify MS-OXCMSG requirement: MS-OXCMSG_R687 // If the e-mail in the Inbox one more than before Call RopSaveChangeMessage, then R687 will be verified. this.Site.CaptureRequirementIfAreEqual<uint>( rowCount + 1, getContentsTableResponse.RowCount, 687, @"[In RopCreateMessage ROP] The RopCreateMessage ROP ([MS-OXCROPS] section 2.2.6.2) is used to create a new Message object."); // Add the debug information this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCMSG_R700"); // Verify MS-OXCMSG requirement: MS-OXCMSG_R700 this.Site.CaptureRequirementIfAreEqual<uint>( rowCount + 1, getContentsTableResponse.RowCount, 700, @"[In RopSaveChangesMessage ROP] The RopSaveChangesMessage ROP ([MS-OXCROPS] section 2.2.6.3) commits the changes made to the Message object."); #endregion #endregion #region Call RopSetColumns to sets the properties visible on contents table. PropertyTag[] propertyTags = new PropertyTag[1]; // The PropertyTag of PidTagMid. propertyTags[0] = new PropertyTag(0x674A, (ushort)PropertyType.PtypInteger64); RopSetColumnsRequest setColumnsRequest = new RopSetColumnsRequest() { RopId = (byte)RopId.RopSetColumns, LogonId = CommonLogonId, // Set InputHandleIndex to 0x00, which specifies the location in the Server object handle table where the handle // for the input Server object is stored, as specified in [MS-OXCROPS]. InputHandleIndex = CommonInputHandleIndex, SetColumnsFlags = (byte)AsynchronousFlags.None, PropertyTagCount = (ushort)propertyTags.Length, PropertyTags = propertyTags }; this.ResponseSOHs = this.MSOXCMSGAdapter.DoRopCall(setColumnsRequest, contentTableHandle, ref this.response, ref this.rawData, GetPropertiesFlags.None); RopSetColumnsResponse setColumnsResponse = (RopSetColumnsResponse)this.response; Site.Assert.AreEqual<uint>(TestSuiteBase.Success, setColumnsResponse.ReturnValue, "Call RopSetColumns should success."); #endregion #region Call RopQueryRows to retrieve rows from contents table. RopQueryRowsRequest queryRowsRequest = new RopQueryRowsRequest() { RopId = (byte)RopId.RopQueryRows, LogonId = CommonLogonId, InputHandleIndex = CommonInputHandleIndex, QueryRowsFlags = (byte)QueryRowsFlags.Advance, ForwardRead = 0x01, RowCount = 0x1000 }; this.ResponseSOHs = this.MSOXCMSGAdapter.DoRopCall(queryRowsRequest, contentTableHandle, ref this.response, ref this.rawData, GetPropertiesFlags.None); RopQueryRowsResponse queryRowsResponse = (RopQueryRowsResponse)this.response; Site.Assert.AreEqual<uint>(TestSuiteBase.Success, setColumnsResponse.ReturnValue, "Call RopQueryRowsRequest should success."); ulong messageID = 0; foreach (PropertyRow row in queryRowsResponse.RowData.PropertyRows) { ulong actualMID = BitConverter.ToUInt64(row.PropertyValues[0].Value, 0); if (actualMID == saveChangesMessageResponse.MessageId) { messageID = actualMID; break; } } Site.Assert.AreNotEqual<ulong>(messageID, 0, "The Message ID should in the contents table of the specified Folder object"); #endregion #region Call RopOpenMessage to open the specific Message object. RopOpenMessageRequest openMessageRequest = new RopOpenMessageRequest() { RopId = (byte)RopId.RopOpenMessage, LogonId = CommonLogonId, InputHandleIndex = CommonInputHandleIndex, OutputHandleIndex = CommonOutputHandleIndex, CodePageId = 0x0FFF, // Code page of Logon object is used FolderId = logonResponse.FolderIds[4], OpenModeFlags = 0x00, MessageId = messageID }; this.ResponseSOHs = this.MSOXCMSGAdapter.DoRopCall(openMessageRequest, this.insideObjHandle, ref this.response, ref this.rawData, GetPropertiesFlags.None); RopOpenMessageResponse openMessageResponse = (RopOpenMessageResponse)this.response; Site.Assert.AreEqual<uint>(TestSuiteBase.Success, setColumnsResponse.ReturnValue, "Call RopOpenMessage should success."); #region Verify MS-OXCMSG_R647, MS-OXCMSG_R372 // Add the debug information this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCMSG_R647"); // Verify MS-OXCMSG requirement: MS-OXCMSG_R647 this.Site.CaptureRequirementIfAreEqual<uint>( TestSuiteBase.Success, openMessageResponse.ReturnValue, 647, @"[In RopOpenMessage ROP] The RopOpenMessage ROP ([MS-OXCROPS] section 2.2.6.1) provides access to an existing Message object, which is identified by the message ID (MID), whose structure is specified in [MS-OXCDATA] section 2.2.1.2.<7>"); // Add the debug information this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCMSG_R251"); // Verify MS-OXCMSG requirement: MS-OXCMSG_R251 this.Site.CaptureRequirementIfAreEqual<uint>( TestSuiteBase.Success, openMessageResponse.ReturnValue, 251, @"[In Sending a RopOpenMessage ROP Request] The MID is accessible from the contents table of the Folder object that contains the Message object by including the PidTagMid property ([MS-OXCFXICS] section 2.2.1.2.1) in a RopSetColumns ROP request ([MS-OXCROPS] section 2.2.5.1), as specified in [MS-OXCTABL] section 2.2.2.2."); #endregion #endregion #region Call RopRelease to release all resources this.ReleaseRop(targetMessageHandle); #endregion }
public void MSOXCMSG_S04_TC01_GeneralPropertiesOnMessageObject() { this.CheckMapiHttpIsSupported(); this.ConnectToServer(ConnectionType.PrivateMailboxServer); #region Call RopLogon to logon the private mailbox. RopLogonResponse logonResponse = this.Logon(LogonType.Mailbox, out this.insideObjHandle); #endregion #region Call RopOpenFolder to open inbox folder. uint folderHandle = this.OpenSpecificFolder(logonResponse.FolderIds[4], this.insideObjHandle); #endregion #region Call RopCreateMessage to create Message object. uint targetMessageHandle = this.CreatedMessage(logonResponse.FolderIds[4], this.insideObjHandle); #endregion #region Call RopModifyRecipients to add recipient to message created by step2 PropertyTag[] recipientColumns = this.CreateRecipientColumns(); List<ModifyRecipientRow> modifyRecipientRow = new List<ModifyRecipientRow> { this.CreateModifyRecipientRow(Common.GetConfigurationPropertyValue("AdminUserName", this.Site), 0) }; this.AddRecipients(modifyRecipientRow, targetMessageHandle, recipientColumns); #endregion #region Call RopGetPropertiesSpecific to get PidTagMessageFlags property for created message before save message. // Prepare property Tag PropertyTag[] tagArray = new PropertyTag[1]; tagArray[0] = PropertyHelper.PropertyTagDic[PropertyNames.PidTagMessageFlags]; // Get properties for Created Message RopGetPropertiesSpecificRequest getPropertiesSpecificRequest = new RopGetPropertiesSpecificRequest() { RopId = (byte)RopId.RopGetPropertiesSpecific, 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. PropertySizeLimit = 0xFFFF, // This value specifies the maximum number of the property PropertyTagCount = (ushort)tagArray.Length, PropertyTags = tagArray }; this.ResponseSOHs = this.MSOXCMSGAdapter.DoRopCall(getPropertiesSpecificRequest, targetMessageHandle, ref this.response, ref this.rawData, GetPropertiesFlags.None); RopGetPropertiesSpecificResponse getPropertiesSpecificResponse = (RopGetPropertiesSpecificResponse)this.response; Site.Assert.AreEqual<uint>(TestSuiteBase.Success, getPropertiesSpecificResponse.ReturnValue, TestSuiteBase.ROPSucceedMsg); List<PropertyObj> ps = PropertyHelper.GetPropertyObjFromBuffer(tagArray, getPropertiesSpecificResponse); PropertyObj pidTagMessageFlags = PropertyHelper.GetPropertyByName(ps, PropertyNames.PidTagMessageFlags); #endregion #region Call RopSetProperties to set PidTagMessageFlags property of created message. List<PropertyObj> propertyList = this.SetGeneralPropertiesOfMessage(); int messageFlags = Convert.ToInt32(pidTagMessageFlags.Value) | (int)MessageFlags.MfResend; propertyList.Add(new PropertyObj(PropertyNames.PidTagMessageFlags, BitConverter.GetBytes(messageFlags))); this.SetPropertiesForMessage(targetMessageHandle, propertyList); #endregion #region Call RopSaveChangesMessage to save created message. RopSaveChangesMessageResponse saveChangesMessageResponse = this.SaveMessage(targetMessageHandle, (byte)SaveFlags.ForceSave); // The message ID of specific message created by above step. ulong messageId = saveChangesMessageResponse.MessageId; #endregion #region Call RopGetContentsTable to get the contents table of inbox folder before submit message. RopGetContentsTableResponse getContentsTableResponse = this.GetContentTableSuccess(folderHandle); uint contentTableHandle = this.ResponseSOHs[0][getContentsTableResponse.OutputHandleIndex]; uint rowCountBeforeSubmit = getContentsTableResponse.RowCount; this.ReleaseRop(contentTableHandle); #endregion #region Call RopSubmitMessage to submit message RopSubmitMessageRequest submitMessageRequest = new RopSubmitMessageRequest() { RopId = (byte)RopId.RopSubmitMessage, LogonId = CommonLogonId, InputHandleIndex = CommonInputHandleIndex, SubmitFlags = (byte)SubmitFlags.None }; this.ResponseSOHs = this.MSOXCMSGAdapter.DoRopCall(submitMessageRequest, targetMessageHandle, ref this.response, ref this.rawData, GetPropertiesFlags.None); RopSubmitMessageResponse submitMessageResponse = (RopSubmitMessageResponse)this.response; Site.Assert.AreEqual<uint>(TestSuiteBase.Success, submitMessageResponse.ReturnValue, "Call RopSubmitMessage should success."); #endregion #region Call RopOpenMessage to open created message. RopOpenMessageRequest openMessageRequest = new RopOpenMessageRequest { RopId = (byte)RopId.RopOpenMessage, LogonId = CommonLogonId, InputHandleIndex = CommonInputHandleIndex, OutputHandleIndex = CommonOutputHandleIndex, CodePageId = 0x0FFF, FolderId = logonResponse.FolderIds[4], OpenModeFlags = (byte)MessageOpenModeFlags.ReadOnly, MessageId = messageId }; this.ResponseSOHs = this.MSOXCMSGAdapter.DoRopCall(openMessageRequest, this.insideObjHandle, ref this.response, ref this.rawData, GetPropertiesFlags.None); RopOpenMessageResponse openMessageResponse = (RopOpenMessageResponse)this.response; Site.Assert.AreEqual<uint>(TestSuiteBase.Success, openMessageResponse.ReturnValue, "Call RopOpenMessage should success."); targetMessageHandle = this.ResponseSOHs[0][openMessageResponse.OutputHandleIndex]; #region Verify MS-OXCMSG_R676, MS-OXCMSG_R678 and MS-OXCMSG_R1298 string subjectPrefixInOpenResponse = System.Text.ASCIIEncoding.ASCII.GetString(openMessageResponse.SubjectPrefix.String); // Add the debug information this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCMSG_R676"); // Verify MS-OXCMSG requirement: MS-OXCMSG_R676 this.Site.CaptureRequirementIfAreEqual<string>( TestDataOfPidTagSubjectPrefix, subjectPrefixInOpenResponse.Substring(0, subjectPrefixInOpenResponse.Length - 1), 676, @"[In RopOpenMessage ROP Response Buffer] [SubjectPrefix] The SubjectPrefix field contains the value of the PidTagSubjectPrefix property (section 2.2.1.9)."); string normalizedSubjectInOpenResponse = System.Text.ASCIIEncoding.ASCII.GetString(openMessageResponse.NormalizedSubject.String); // Add the debug information this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCMSG_R678"); // Verify MS-OXCMSG requirement: MS-OXCMSG_R678 this.Site.CaptureRequirementIfAreEqual<string>( TestSuiteBase.TestDataOfPidTagNormalizedSubject, normalizedSubjectInOpenResponse.Substring(0, normalizedSubjectInOpenResponse.Length - 1), 678, @"[In RopOpenMessage ROP Response Buffer] [NormalizedSubject] The NormalizedSubject field contains the value of the PidTagNormalizedSubject property (section 2.2.1.10)."); // Add the debug information this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCMSG_R1298"); // Verify MS-OXCMSG requirement: MS-OXCMSG_R1298 this.Site.CaptureRequirementIfAreEqual<int>( 0x10, openMessageResponse.RecipientRows[0].RecipientType, 1298, @"[In RopOpenMessage ROP Response Buffer] [RecipientRows] The value 0x10 means when resending a previous failure, this flag indicates that this recipient (1) did not successfully receive the message on the previous attempt."); #endregion #endregion #region Call RopGetPropertiesAll to get all properties of created message. RopGetPropertiesAllRequest getPropertiesAllRequest = new RopGetPropertiesAllRequest() { RopId = (byte)RopId.RopGetPropertiesAll, LogonId = CommonLogonId, InputHandleIndex = CommonInputHandleIndex, // Set PropertySizeLimit,which specifies the maximum size allowed for a property value returned, // as specified in [MS-OXCROPS] section 2.2.8.4.1. PropertySizeLimit = 0xFFFF, WantUnicode = 1, }; // In process, call capture code to verify adapter requirement this.ResponseSOHs = this.MSOXCMSGAdapter.DoRopCall(getPropertiesAllRequest, targetMessageHandle, ref this.response, ref this.rawData, GetPropertiesFlags.MessageProperties); RopGetPropertiesAllResponse getPropertiesAllResponse = (RopGetPropertiesAllResponse)this.response; Site.Assert.AreEqual<uint>(TestSuiteBase.Success, getPropertiesAllResponse.ReturnValue, "Call RopGetPropertiesAll should success."); List<PropertyObj> propertyValues = PropertyHelper.GetPropertyObjFromBuffer(getPropertiesAllResponse); PropertyObj pidTagImportance = PropertyHelper.GetPropertyByName(propertyValues, PropertyNames.PidTagImportance); PropertyObj pidTagPriority = PropertyHelper.GetPropertyByName(propertyValues, PropertyNames.PidTagPriority); PropertyObj pidTagSensitivity = PropertyHelper.GetPropertyByName(propertyValues, PropertyNames.PidTagSensitivity); PropertyObj pidTagTrustSender = PropertyHelper.GetPropertyByName(propertyValues, PropertyNames.PidTagTrustSender); PropertyObj pidTagSubject = PropertyHelper.GetPropertyByName(propertyValues, PropertyNames.PidTagSubject); PropertyObj pidTagSubjectPrefix = PropertyHelper.GetPropertyByName(propertyValues, PropertyNames.PidTagSubjectPrefix); PropertyObj pidTagNormalizedSubject = PropertyHelper.GetPropertyByName(propertyValues, PropertyNames.PidTagNormalizedSubject); #region Verify requirements // Add the debug information this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCMSG_R1668 ,the property count is {0}.", getPropertiesAllResponse.PropertyValueCount); // Verify MS-OXCMSG requirement: MS-OXCMSG_R1668 bool isVerifiedR1668 = getPropertiesAllResponse.PropertyValueCount > 0; this.Site.CaptureRequirementIfIsTrue( isVerifiedR1668, 1668, @"[In RopOpenMessage ROP Response Buffer] [HasNamedProperties] Nonzero: Named properties are defined for this Message object and can be obtained through a RopGetPropertiesAll ROP request ([MS-OXCROPS] section 2.2.8.4)."); // Add the debug information this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCMSG_R72"); // Verify MS-OXCMSG requirement: MS-OXCMSG_R72 this.Site.CaptureRequirementIfAreEqual<int>( 0x00000000, Convert.ToInt32(pidTagImportance.Value), 72, @"[In PidTagImportance Property] [The value 0x00000000 indicates the level of importance assigned by the end user to the Message object is] Low importance."); // Add the debug information this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCMSG_R80"); // Verify MS-OXCMSG requirement: MS-OXCMSG_R80 this.Site.CaptureRequirementIfAreEqual<int>( -1, Convert.ToInt32(pidTagPriority.Value), 80, @"[In PidTagPriority Property] [The value 0xFFFFFFFF indicates the client's request for the priority is] Not urgent."); // Add the debug information this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCMSG_R86"); // Verify MS-OXCMSG requirement: MS-OXCMSG_R86 this.Site.CaptureRequirementIfAreEqual<int>( 0x00000001, Convert.ToInt32(pidTagSensitivity.Value), 86, @"[In PidTagSensitivity Property] [The value 0x00000001 indicates the sender's assessment of the sensitivity of the Message object is] Personal."); if (Common.IsRequirementEnabled(1713, this.Site)) { // Add the debug information this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCMSG_R1236"); // Verify MS-OXCMSG requirement: MS-OXCMSG_R1236 this.Site.CaptureRequirementIfAreEqual<int>( 0x00000001, (int)pidTagTrustSender.Value, 1236, @"[In PidTagTrustSender] The value 0x00000001 indicates that the message was delivered through a trusted transport channel."); // Add the debug information this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCMSG_R1713"); // Verify MS-OXCMSG requirement: MS-OXCMSG_R1713 this.Site.CaptureRequirementIfIsNotNull( pidTagTrustSender.Value, 1713, @"[In Appendix A: Product Behavior] Implementation does support the PidTagTrustSender property. (Exchange 2007 follows this behavior.)"); } PropertyObj pidTagPurportedSenderDomain = PropertyHelper.GetPropertyByName(propertyValues, PropertyNames.PidTagPurportedSenderDomain); // Add the debug information this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCMSG_R1214"); // Verify MS-OXCMSG requirement: MS-OXCMSG_R1214 this.Site.CaptureRequirementIfAreEqual<string>( Common.GetConfigurationPropertyValue("Domain", this.Site), pidTagPurportedSenderDomain.Value.ToString(), 1214, @"[In PidTagPurportedSenderDomain Property] The PidTagPurportedSenderDomain property ([MS-OXPROPS] section 2.865) contains the domain name of the last sender responsible for transmitting the current message."); PropertyObj pidTagAlternateRecipientAllowed = PropertyHelper.GetPropertyByName(propertyValues, PropertyNames.PidTagAlternateRecipientAllowed); // Add the debug information this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCMSG_R1797"); // Verify MS-OXCMSG requirement: MS-OXCMSG_R1797 this.Site.CaptureRequirementIfIsTrue( Convert.ToBoolean(pidTagAlternateRecipientAllowed.Value), 1797, @"[In PidTagAlternateRecipientAllowed Property] This property [PidTagAlternateRecipientAllowed] is set to ""TRUE"" if autoforwarding is allowed."); PropertyObj pidTagResponsibility = PropertyHelper.GetPropertyByName(propertyValues, PropertyNames.PidTagResponsibility); // Add the debug information this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCMSG_R1198"); // Verify MS-OXCMSG requirement: MS-OXCMSG_R1198 this.Site.CaptureRequirementIfIsTrue( Convert.ToBoolean(pidTagResponsibility.Value), 1198, @"[In PidTagResponsibility Property] This property [PidTagResponsibility] is set to ""TRUE"" if another agent has accepted responsibility."); pidTagMessageFlags = PropertyHelper.GetPropertyByName(propertyValues, PropertyNames.PidTagMessageFlags); // Add the debug information this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCMSG_R515"); // Verify MS-OXCMSG requirement: MS-OXCMSG_R515 this.Site.CaptureRequirementIfAreEqual<int>( 0x00000080, Convert.ToInt32(pidTagMessageFlags.Value) & 0x00000080, 515, @"[In PidTagMessageFlags Property] [mfResend (0x00000080)] The message includes a request for a resend operation with a non-delivery report."); #endregion #endregion #region Call RopGetPropertiesSpecific to get the specific properties of created message. List<PropertyTag> propertiesOfMessage = this.GetPropertyTagListOfMessageObject(); propertyValues = this.GetSpecificPropertiesOfMessage(logonResponse.FolderIds[4], messageId, this.insideObjHandle, propertiesOfMessage); // Parse property response get Property Value to verify test case requirement pidTagImportance = PropertyHelper.GetPropertyByName(propertyValues, PropertyNames.PidTagImportance); pidTagSubjectPrefix = PropertyHelper.GetPropertyByName(propertyValues, PropertyNames.PidTagSubjectPrefix); pidTagNormalizedSubject = PropertyHelper.GetPropertyByName(propertyValues, PropertyNames.PidTagNormalizedSubject); pidTagSubject = PropertyHelper.GetPropertyByName(propertyValues, PropertyNames.PidTagSubject); PropertyObj pidTagRecipientDisplayName = PropertyHelper.GetPropertyByName(propertyValues, PropertyNames.PidTagRecipientDisplayName); #region Verify requirements // Add the debug information this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCMSG_R58"); // Verify MS-OXCMSG requirement: MS-OXCMSG_R58 this.Site.CaptureRequirementIfAreEqual<string>( TestDataOfPidTagSubjectPrefix, pidTagSubjectPrefix.Value.ToString(), 58, @"[In PidTagSubjectPrefix Property] The PidTagSubjectPrefix property ([MS-OXPROPS] section 2.1096) contains the prefix for the subject of the message."); // Add the debug information this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCMSG_R64"); // Verify MS-OXCMSG requirement: MS-OXCMSG_R64 this.Site.CaptureRequirementIfAreEqual<string>( TestSuiteBase.TestDataOfPidTagNormalizedSubject, pidTagNormalizedSubject.Value.ToString(), 64, @"[In PidTagNormalizedSubject Property] The PidTagNormalizedSubject property ([MS-OXPROPS] section 2.877) contains the normalized subject of the message, as specified in [MS-OXCMAIL] section 2.2.3.2.6.1."); // Add the debug information this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCMSG_R1238"); string mailSubject = TestDataOfPidTagSubjectPrefix + TestDataOfPidTagNormalizedSubject; // Verify MS-OXCMSG requirement: MS-OXCMSG_R1238 this.Site.CaptureRequirementIfAreEqual<string>( mailSubject, pidTagSubject.Value.ToString(), 1238, @"[In PidTagSubject Property] The PidTagSubject property ([MS-OXPROPS] section 2.1021) contains the full subject of an e-mail message."); // Add the debug information this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCMSG_R1239"); // Verify MS-OXCMSG requirement: MS-OXCMSG_R1239 this.Site.CaptureRequirementIfAreEqual<string>( mailSubject, pidTagSubject.Value.ToString(), 1239, @"[In PidTagSubject Property] The full subject is a concatenation of the subject prefix, as identified by the PidTagSubjectPrefix property (section 2.2.1.9), and the normalized subject, as identified by the PidTagNormalizedSubject property (section 2.2.1.10)."); PropertyObj pidTagAutoForwarded = PropertyHelper.GetPropertyByName(propertyValues, PropertyNames.PidTagAutoForwarded); // Add the debug information this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCMSG_R1108"); // Verify MS-OXCMSG requirement: MS-OXCMSG_R1108 this.Site.CaptureRequirementIfAreEqual<byte>( 0x00, Convert.ToByte(pidTagAutoForwarded.Value), 1108, @"[In PidTagAutoForwarded Property] If this property [PidTagAutoForwarded] is unset, a default value of 0x00 is assumed."); // Add the debug information this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCMSG_R2047"); // Verify MS-OXCMSG requirement: MS-OXCMSG_R2047 this.Site.CaptureRequirementIfAreEqual<string>( Common.GetConfigurationPropertyValue("AdminUserName", this.Site), pidTagRecipientDisplayName.Value.ToString(), 2047, @"[In PidTagRecipientDisplayName Property] The PidTagRecipientDisplayName property ([MS-OXPROPS] section 2.888) specifies the display name of a recipient (2)."); #endregion #endregion #region Receive the message sent by step 9. bool isMessageReceived = WaitEmailBeDelivered(folderHandle, rowCountBeforeSubmit); Site.Assert.IsTrue(isMessageReceived, "The message should be received."); #endregion #region Call RopRelease to release all resources. this.ReleaseRop(targetMessageHandle); this.ReleaseRop(folderHandle); #endregion }
public void MSOXCMSG_S05_TC08_RopOpenMessageWithoutRight() { this.CheckMapiHttpIsSupported(); this.ConnectToServer(ConnectionType.PrivateMailboxServer); string commonUser = Common.GetConfigurationPropertyValue("CommonUser", Site); string commonUserPassword = Common.GetConfigurationPropertyValue("CommonUserPassword", Site); string commonUserEssdn = Common.GetConfigurationPropertyValue("CommonUserEssdn", Site); uint pidTagMemberRights; #region Call RopLogon to logon the private mailbox with administrator. RopLogonResponse logonResponse = this.Logon(LogonType.Mailbox, out this.insideObjHandle); #endregion #region Call RopOpenFolder to open the inbox folder. ulong parentFolderId = logonResponse.FolderIds[4]; uint openedInboxFolderHandle = this.OpenSpecificFolder(parentFolderId, this.insideObjHandle); #endregion #region Call RopCreateFolder to create a new subfolder. ulong thirdSubfolderId; uint thirdSubFolderHandle = this.CreateSubFolder(openedInboxFolderHandle, out thirdSubfolderId); LongTermId thirdSubfolderLongTermID = this.GetLongTermIdFormID(thirdSubfolderId, this.insideObjHandle); #endregion #region Call RopCreateMessage and RopSaveChangesMessage to create a Message object in subfolder created. // Create a message in InBox this.MessageHandle = this.CreatedMessage(thirdSubfolderId, this.insideObjHandle); RopSaveChangesMessageResponse saveChangesMessageResponse = this.SaveMessage(this.MessageHandle, (byte)SaveFlags.KeepOpenReadWrite); ulong thirdMessageId = saveChangesMessageResponse.MessageId; LongTermId thirdMessageLongTermID = this.GetLongTermIdFormID(thirdMessageId, this.insideObjHandle); this.ReleaseRop(this.MessageHandle); #endregion #region Add Read permission to "CommonUser" on inbox folder. // Add folder visible permission for the inbox. pidTagMemberRights = (uint)PidTagMemberRights.FolderVisible | (uint)PidTagMemberRights.ReadAny; this.AddPermission(commonUserEssdn, pidTagMemberRights, openedInboxFolderHandle); #endregion #region Add Read and write permission to "CommonUser" on subfolder pidTagMemberRights = (uint)PidTagMemberRights.FolderVisible; this.AddPermission(commonUserEssdn, pidTagMemberRights, thirdSubFolderHandle); #endregion #region Call RopLogon to logon the private mailbox with "CommonUser" this.rawData = null; this.insideObjHandle = 0; this.response = null; this.ResponseSOHs = null; this.MSOXCMSGAdapter.RpcDisconnect(); this.MSOXCMSGAdapter.Reset(); this.MSOXCMSGAdapter.RpcConnect(ConnectionType.PrivateMailboxServer, commonUser, commonUserPassword, commonUserEssdn); string userDN = Common.GetConfigurationPropertyValue("AdminUserEssdn", this.Site) + "\0"; RopLogonRequest logonRequest = new RopLogonRequest() { RopId = (byte)RopId.RopLogon, LogonId = CommonLogonId, OutputHandleIndex = 0x00, // This index specifies the location 0x00 in the Server Object Handle Table where the handle for the output Server Object is stored. StoreState = 0, LogonFlags = 0x01, // Logon to a private mailbox OpenFlags = (uint)OpenFlags.UsePerMDBReplipMapping, // Requesting admin access to the mail box EssdnSize = (ushort)Encoding.ASCII.GetByteCount(userDN), Essdn = Encoding.ASCII.GetBytes(userDN) }; this.ResponseSOHs = this.MSOXCMSGAdapter.DoRopCall(logonRequest, this.insideObjHandle, ref this.response, ref this.rawData, GetPropertiesFlags.None); logonResponse = (RopLogonResponse)this.response; Site.Assert.AreEqual<uint>(TestSuiteBase.Success, logonResponse.ReturnValue, "Call RopLogon should success."); uint objHandle = this.ResponseSOHs[0][logonResponse.OutputHandleIndex]; #endregion #region Call RopOpenMessage to open a message that the user does not have rights to the message. thirdSubfolderId = this.GetObjectIdFormLongTermID(thirdSubfolderLongTermID, objHandle); thirdMessageId = this.GetObjectIdFormLongTermID(thirdMessageLongTermID, objHandle); RopOpenMessageRequest openMessageRequest = new RopOpenMessageRequest() { RopId = (byte)RopId.RopOpenMessage, LogonId = CommonLogonId, InputHandleIndex = CommonInputHandleIndex, OutputHandleIndex = CommonOutputHandleIndex, CodePageId = 0x0FFF, // Code page of Logon object is used FolderId = thirdSubfolderId, OpenModeFlags = (byte)MessageOpenModeFlags.ReadWrite, MessageId = thirdMessageId }; this.ResponseSOHs = this.MSOXCMSGAdapter.DoRopCall(openMessageRequest, objHandle, ref this.response, ref this.rawData, GetPropertiesFlags.None); RopOpenMessageResponse openMessageResponse = (RopOpenMessageResponse)this.response; #region Verify requirements // Add the debug information this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCMSG_R324"); // Verify MS-OXCMSG requirement: MS-OXCMSG_R324 this.Site.CaptureRequirementIfAreNotEqual<uint>( TestSuiteBase.Success, openMessageResponse.ReturnValue, 324, @"[in Receiving a RopOpenMessage ROP Request] RopOpenMessage MUST NOT succeed if the client has insufficient access rights to the folder in which the Message object is stored."); // Add the debug information this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCMSG_R2184"); // Verify MS-OXCMSG requirement: MS-OXCMSG_R2184 this.Site.CaptureRequirementIfAreEqual<uint>( 0x80070005, openMessageResponse.ReturnValue, 2184, @"[In Receiving a RopOpenMessage ROP Request] [ecAccessDenied(0x80070005)] The user does not have rights to the message."); #endregion #endregion #region Call RopLogon to logon the private mailbox with administrator this.rawData = null; this.insideObjHandle = 0; this.response = null; this.ResponseSOHs = null; this.MSOXCMSGAdapter.RpcDisconnect(); this.MSOXCMSGAdapter.Reset(); this.ConnectToServer(ConnectionType.PrivateMailboxServer); logonResponse = this.Logon(LogonType.Mailbox, out this.insideObjHandle); openedInboxFolderHandle = this.OpenSpecificFolder(logonResponse.FolderIds[4], this.insideObjHandle); #endregion #region Call RopDeleteFolder to delete the subfolder created thirdSubfolderId = this.GetObjectIdFormLongTermID(thirdSubfolderLongTermID, this.insideObjHandle); RopDeleteFolderRequest deleteFolderRequest = new RopDeleteFolderRequest() { RopId = (byte)RopId.RopDeleteFolder, LogonId = CommonLogonId, InputHandleIndex = CommonInputHandleIndex, DeleteFolderFlags = (byte)DeleteFolderFlags.DeleteHardDelete | (byte)DeleteFolderFlags.DelMessages, FolderId = thirdSubfolderId }; this.ResponseSOHs = this.MSOXCMSGAdapter.DoRopCall(deleteFolderRequest, openedInboxFolderHandle, ref this.response, ref this.rawData, GetPropertiesFlags.None); RopDeleteFolderResponse deleteFolderresponse = (RopDeleteFolderResponse)this.response; Site.Assert.AreEqual<uint>(TestSuiteBase.Success, deleteFolderresponse.ReturnValue, "Call RopDeleteFolder should success."); #endregion }
public void MSOXCMSG_S05_TC04_OpenSoftDeletedMessage() { this.CheckMapiHttpIsSupported(); this.ConnectToServer(ConnectionType.PrivateMailboxServer); #region Call RopLogon to logon the private mailbox. RopLogonResponse logonResponse = this.Logon(LogonType.Mailbox, out this.insideObjHandle); #endregion #region Call RopOpenFolder to open inbox folder uint openedFolderHandle = this.OpenSpecificFolder(logonResponse.FolderIds[4], this.insideObjHandle); #endregion #region Call RopCreateMessage to create Message object. uint targetMessageHandleForDelete = this.CreatedMessage(logonResponse.FolderIds[4], this.insideObjHandle); #endregion #region Call RopSaveChangesMessage to save created message. RopSaveChangesMessageResponse saveChangesMessageResponse = this.SaveMessage(targetMessageHandleForDelete, (byte)SaveFlags.ForceSave); ulong messageIdForDelete = saveChangesMessageResponse.MessageId; #endregion this.ReleaseRop(targetMessageHandleForDelete); #region Call RopDeleteMessages to soft delete created message. RopDeleteMessagesRequest deleteMessagesRequest = new RopDeleteMessagesRequest() { RopId = (byte)RopId.RopDeleteMessages, LogonId = CommonLogonId, InputHandleIndex = CommonInputHandleIndex, WantAsynchronous = 0x00, // The server does not generate a non-read receipt for the deleted messages. NotifyNonRead = 0x00, MessageIdCount = 1, MessageIds = new ulong[] { messageIdForDelete }, }; this.ResponseSOHs = this.MSOXCMSGAdapter.DoRopCall(deleteMessagesRequest, openedFolderHandle, ref this.response, ref this.rawData, GetPropertiesFlags.None); RopDeleteMessagesResponse deleteMessagesResponse = (RopDeleteMessagesResponse)this.response; Site.Assert.AreEqual<uint>(TestSuiteBase.Success, deleteMessagesResponse.ReturnValue, "Call RopDeleteMessages should success."); #endregion #region Call RopOpenMessage which OpenModeFlags is not OpenSoftDeleted to open soft deleted message. RopOpenMessageRequest openMessageRequest = new RopOpenMessageRequest() { RopId = (byte)RopId.RopOpenMessage, LogonId = CommonLogonId, InputHandleIndex = CommonInputHandleIndex, OutputHandleIndex = CommonOutputHandleIndex, CodePageId = 0x0FFF, // Code page of Logon object is used FolderId = logonResponse.FolderIds[4], // Open the message in INBOX folder in which message is created. OpenModeFlags = (byte)MessageOpenModeFlags.ReadWrite, MessageId = messageIdForDelete // Open the saved message }; this.ResponseSOHs = this.MSOXCMSGAdapter.DoRopCall(openMessageRequest, this.insideObjHandle, ref this.response, ref this.rawData, GetPropertiesFlags.None); RopOpenMessageResponse openMessageResponse = (RopOpenMessageResponse)this.response; #region Verify MS-OXCMSG_R335, MS-OXCMSG_R326 // Add the debug information this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCMSG_R335"); // Verify MS-OXCMSG requirement: MS-OXCMSG_R335 this.Site.CaptureRequirementIfAreEqual<uint>( 0x8004010F, openMessageResponse.ReturnValue, 335, @"[In Receiving a RopOpenMessage ROP Request] [ecNotFound (0x8004010F)] The message is soft deleted and the client has not specified the OpenSoftDeleted flag as part of the OpenModeFlag field."); // Add the debug information this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCMSG_R326"); // Verify MS-OXCMSG requirement: MS-OXCMSG_R326 this.Site.CaptureRequirementIfAreNotEqual<uint>( TestSuiteBase.Success, openMessageResponse.ReturnValue, 326, @"[In Receiving a RopOpenMessage ROP Request] If the OpenSoftDeleted flag is not included, the server MUST NOT provide access to soft deleted Message objects."); #endregion #endregion #region Call RopRelease to release the created message this.ReleaseRop(openedFolderHandle); #endregion }
public void MSOXCMSG_S05_TC03_RopOpenMessageFailure() { this.CheckMapiHttpIsSupported(); this.ConnectToServer(ConnectionType.PrivateMailboxServer); #region Call RopLogon to logon the private mailbox. RopLogonResponse logonResponse = this.Logon(LogonType.Mailbox, out this.insideObjHandle); #endregion #region Call RopCreateMessage to create a Message object. uint targetMessageHandle = this.CreatedMessage(logonResponse.FolderIds[4], this.insideObjHandle); #endregion #region Call RopSaveChangesMessage to save created message. RopSaveChangesMessageResponse saveChangesMessageResponse = this.SaveMessage(targetMessageHandle, (byte)SaveFlags.ForceSave); ulong targetMessageId = saveChangesMessageResponse.MessageId; #endregion #region Call RopOpenMessage to open a message which does not exist. RopOpenMessageRequest openMessageRequest = new RopOpenMessageRequest() { RopId = (byte)RopId.RopOpenMessage, LogonId = CommonLogonId, InputHandleIndex = CommonInputHandleIndex, OutputHandleIndex = CommonOutputHandleIndex, CodePageId = 0x0FFF, // Code page of Logon object is used FolderId = logonResponse.FolderIds[4], // Open the message in INBOX folder in which message is created. OpenModeFlags = 0x00, // The message will be opened as read-only MessageId = targetMessageId - 1 // The specified ID does not exist. }; this.ResponseSOHs = this.MSOXCMSGAdapter.DoRopCall(openMessageRequest, this.insideObjHandle, ref this.response, ref this.rawData, GetPropertiesFlags.None); RopOpenMessageResponse openMessageResponse = (RopOpenMessageResponse)this.response; #region Verify MS-OXCMSG_R323, MS-OXCMSG_R1477 and MS-OXCMSG_R333 // Add the debug information this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCMSG_R323"); // Verify MS-OXCMSG requirement: MS-OXCMSG_R323 this.Site.CaptureRequirementIfAreNotEqual<uint>( TestSuiteBase.Success, openMessageResponse.ReturnValue, 323, @"[In Receiving a RopOpenMessage ROP Request] A RopOpenMessage ROP MUST NOT succeed if a Message object with the specified ID does not exist."); // Add the debug information this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCMSG_R1477"); // Verify MS-OXCMSG requirement: MS-OXCMSG_R1477 this.Site.CaptureRequirementIfAreEqual<uint>( 0x8004010F, openMessageResponse.ReturnValue, 1477, @"[In Receiving a RopOpenMessage ROP Request] [ecNotFound (0x8004010F)] The folder corresponding to the FID ([MS-OXCDATA] section 2.2.1.1) entered in the ROP request buffer does not contain a message with the entered MID."); // Add the debug information this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCMSG_R333"); // Verify MS-OXCMSG requirement: MS-OXCMSG_R333 this.Site.CaptureRequirementIfAreEqual<uint>( 0x8004010F, openMessageResponse.ReturnValue, 333, @"[In Receiving a RopOpenMessage ROP Request] [ecNotFound (0x8004010F)] The MID ([MS-OXCDATA] section 2.2.1.2) does not correspond to a message in the database."); #endregion #endregion #region Call RopOpenMessage to open a message and the value of the InputHandleIndex field on which this ROP was called does not refer to a Folder object or a Store object. openMessageRequest = new RopOpenMessageRequest() { RopId = (byte)RopId.RopOpenMessage, LogonId = CommonLogonId, InputHandleIndex = CommonOutputHandleIndex, // the value of the InputHandleIndex field does not refer to a Folder object or a Store object. OutputHandleIndex = CommonOutputHandleIndex, CodePageId = 0x0FFF, // Code page of Logon object is used FolderId = logonResponse.FolderIds[4], // Open the message in INBOX folder in which message is created. OpenModeFlags = 0x00, // The message will be opened as read-only MessageId = targetMessageId }; this.ResponseSOHs = this.MSOXCMSGAdapter.DoRopCall(openMessageRequest, this.insideObjHandle, ref this.response, ref this.rawData, GetPropertiesFlags.None); openMessageResponse = (RopOpenMessageResponse)this.response; #region Verify MS-OXCMSG_R1478 // Add the debug information this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCMSG_R1478"); // Verify MS-OXCMSG requirement: MS-OXCMSG_R1478 this.Site.CaptureRequirementIfAreEqual<uint>( 0x000004b9, openMessageResponse.ReturnValue, 1478, @"[In Receiving a RopOpenMessage ROP Request] ecNullObject (0x000004b9)] The value of the InputHandleIndex field on which this ROP was called does not refer to a Folder object or a Store object"); #endregion #endregion #region Call RopRelease to release the created message. this.ReleaseRop(targetMessageHandle); #endregion }
public void MSOXCMSG_S05_TC02_IgnoreOpenModeFlagsOnRopOpenMessage() { this.CheckMapiHttpIsSupported(); this.ConnectToServer(ConnectionType.PrivateMailboxServer); #region Call RopLogon to logon the private mailbox. RopLogonResponse logonResponse = this.Logon(LogonType.Mailbox, out this.insideObjHandle); #endregion #region Call RopCreateMessage to create a Message object. uint targetMessageHandle = this.CreatedMessage(logonResponse.FolderIds[4], this.insideObjHandle); #endregion #region Call RopSaveChangesMessage to save created message. RopSaveChangesMessageResponse saveChangesMessageResponse = this.SaveMessage(targetMessageHandle, (byte)SaveFlags.ForceSave); #endregion #region Call RopOpenMessage and OpenModeFlags is 0x08 to open the created message. RopOpenMessageRequest openMessageRequestFirst = new RopOpenMessageRequest() { RopId = (byte)RopId.RopOpenMessage, LogonId = CommonLogonId, InputHandleIndex = CommonInputHandleIndex, OutputHandleIndex = CommonOutputHandleIndex, CodePageId = 0x0FFF, // Code page of Logon object is used FolderId = logonResponse.FolderIds[4], // Open the message in INBOX folder in which message is created. OpenModeFlags = 0x08, // The OpenModeFlags other bit are set, server should ignore this bit. MessageId = saveChangesMessageResponse.MessageId // Open the saved message }; this.ResponseSOHs = this.MSOXCMSGAdapter.DoRopCall(openMessageRequestFirst, this.insideObjHandle, ref this.response, ref this.rawData, GetPropertiesFlags.None); RopOpenMessageResponse openMessageResponseFirst = (RopOpenMessageResponse)this.response; Site.Assert.AreEqual<uint>(TestSuiteBase.Success, openMessageResponseFirst.ReturnValue, "Call RopOpenMessage should success."); uint openedMessageHandleFirst = this.ResponseSOHs[0][openMessageResponseFirst.OutputHandleIndex]; #endregion #region Call RopOpenMessage and OpenModeFlags is 0x0B to open the created message. RopOpenMessageRequest openMessageRequestSecond = new RopOpenMessageRequest() { RopId = (byte)RopId.RopOpenMessage, LogonId = CommonLogonId, InputHandleIndex = CommonInputHandleIndex, OutputHandleIndex = CommonOutputHandleIndex, CodePageId = 0x0FFF, // Code page of Logon object is used FolderId = logonResponse.FolderIds[4], // Open the message in INBOX folder in which message is created. OpenModeFlags = 0x0B, // The OpenModeFlags other bit are set, server should ignore this bit. MessageId = saveChangesMessageResponse.MessageId // Open the saved message }; this.ResponseSOHs = this.MSOXCMSGAdapter.DoRopCall(openMessageRequestSecond, this.insideObjHandle, ref this.response, ref this.rawData, GetPropertiesFlags.None); RopOpenMessageResponse openMessageResponseSecond = (RopOpenMessageResponse)this.response; Site.Assert.AreEqual<uint>(TestSuiteBase.Success, openMessageResponseSecond.ReturnValue, "Call RopOpenMessage should success."); uint openedMessageHandleSecond = this.ResponseSOHs[0][openMessageResponseSecond.OutputHandleIndex]; #endregion #region Verify MS-OXCMSG_R1838, MS-OXCMSG_R1475 // Add the debug information this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCMSG_R1838"); // Verify MS-OXCMSG requirement: MS-OXCMSG_R1838 this.Site.CaptureRequirementIfAreEqual<RopOpenMessageResponse>( openMessageResponseFirst, openMessageResponseSecond, 1838, @"[In RopOpenMessage ROP Request Buffer] The server responses are same when OpenModeFlags are set with two different values, and the two different values are not one of 0x00, 0x01, 0x03 and 0x04."); // Add the debug information this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCMSG_R1475"); // Verify MS-OXCMSG requirement: MS-OXCMSG_R1475 this.Site.CaptureRequirementIfAreNotEqual<uint>( openedMessageHandleFirst, openedMessageHandleSecond, 1475, @"[In Receiving a RopOpenMessage ROP Request] When the server receives multiple requests to open the same Message object, it returns a different handle and maintains a separate transaction (3) for each."); #endregion #region Call RopRelease to release the created message. this.ReleaseRop(openedMessageHandleFirst); this.ReleaseRop(openedMessageHandleSecond); #endregion }
/// <summary> /// Open a specific message. /// </summary> /// <param name="folderId">The folder Id of specific folder that contains specific message.</param> /// <param name="messageId">The message id of specific message.</param> /// <param name="objectHandle">A Server object handle.</param> /// <param name="openFlags">The OpenModeFlags value.</param> /// <param name="openMessageResponse">The response of RopOpenMessage.</param> /// <returns>A Server object handle of specific message.</returns> protected uint OpenSpecificMessage(ulong folderId, ulong messageId, uint objectHandle, MessageOpenModeFlags openFlags, out RopOpenMessageResponse openMessageResponse) { RopOpenMessageRequest openMessageRequest = new RopOpenMessageRequest() { RopId = (byte)RopId.RopOpenMessage, 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. CodePageId = 0x0FFF, // Code page of Logon object is used FolderId = folderId, // Open the message in INBOX folder in which message is created. OpenModeFlags = (byte)openFlags, // The message will be opened as read-only. MessageId = messageId // Open the saved message }; this.ResponseSOHs = this.MSOXCMSGAdapter.DoRopCall(openMessageRequest, objectHandle, ref this.response, ref this.rawData, GetPropertiesFlags.None); openMessageResponse = (RopOpenMessageResponse)this.response; Site.Assert.AreEqual<uint>(TestSuiteBase.Success, openMessageResponse.ReturnValue, "Call RopOpenMessage should success."); return this.ResponseSOHs[0][openMessageRequest.OutputHandleIndex]; }