/// <summary> /// Get the properties' value from the rows of the table. /// </summary> /// <param name="tableHandle">The table handle.</param> /// <param name="rowCount">The amount of the rows.</param> /// <param name="properties">The properties need to show.</param> /// <returns>The property rows in the specified table object.</returns> protected List<PropertyRow> GetTableRowValue(uint tableHandle, ushort rowCount, PropertyTag[] properties) { #region The client calls RopSetColumns operation to set the property information to show. RopSetColumnsRequest setColumnsRequest = new RopSetColumnsRequest(); object ropResponse = new object(); setColumnsRequest.RopId = (byte)RopId.RopSetColumns; setColumnsRequest.LogonId = Constants.CommonLogonId; setColumnsRequest.InputHandleIndex = Constants.CommonInputHandleIndex; setColumnsRequest.PropertyTagCount = (ushort)properties.Length; setColumnsRequest.PropertyTags = properties; setColumnsRequest.SetColumnsFlags = (byte)AsynchronousFlags.None; this.Adapter.DoRopCall(setColumnsRequest, tableHandle, ref ropResponse, ref this.responseHandles); #endregion #region The client calls RopQueryRows operation to query the folder which have the special properties. RopQueryRowsRequest queryRowsRequest = new RopQueryRowsRequest(); ropResponse = new object(); queryRowsRequest.RopId = (byte)RopId.RopQueryRows; queryRowsRequest.LogonId = Constants.CommonLogonId; queryRowsRequest.InputHandleIndex = Constants.CommonInputHandleIndex; queryRowsRequest.RowCount = (ushort)rowCount; queryRowsRequest.QueryRowsFlags = (byte)QueryRowsFlags.Advance; queryRowsRequest.ForwardRead = 0x01; this.Adapter.DoRopCall(queryRowsRequest, tableHandle, ref ropResponse, ref this.responseHandles); RopQueryRowsResponse queryRowsResponse = (RopQueryRowsResponse)ropResponse; Site.Assert.AreEqual<uint>(Constants.SuccessCode, queryRowsResponse.ReturnValue, "RopQueryRows ROP operation performs successful!"); #endregion List<PropertyRow> propertyRows = null; if (queryRowsResponse.RowData != null) { propertyRows = queryRowsResponse.RowData.PropertyRows; } return propertyRows; }
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 }
/// <summary> /// Get the properties' value from the rows of the table. /// </summary> /// <param name="tableHandle">The table handle.</param> /// <param name="rowCount">The amount of the rows.</param> /// <param name="properties">The properties need to show.</param> /// <returns>The property rows in the specified table object.</returns> private List<PropertyRow> GetTableRowValue(uint tableHandle, ushort rowCount, PropertyTag[] properties) { #region The client calls RopSetColumns operation to set the property information to show. RopSetColumnsRequest setColumnsRequest = new RopSetColumnsRequest { RopId = (byte)RopId.RopSetColumns, LogonId = TestSuiteBase.LogonId, InputHandleIndex = TestSuiteBase.InputHandleIndex0, PropertyTagCount = (ushort)properties.Length, PropertyTags = properties, SetColumnsFlags = (byte)AsynchronousFlags.None }; this.responseSOHs = this.cropsAdapter.ProcessSingleRop( setColumnsRequest, tableHandle, ref this.response, ref this.rawData, RopResponseType.SuccessResponse); RopSetColumnsResponse setColumnsResponse = (RopSetColumnsResponse)this.response; Site.Assert.AreEqual<uint>( TestSuiteBase.SuccessReturnValue, setColumnsResponse.ReturnValue, "if ROP succeeds, the ReturnValue of its response is 0(success)"); #endregion #region The client calls RopQueryRows operation to query the folder which have the special properties. RopQueryRowsRequest queryRowsRequest = new RopQueryRowsRequest { RopId = (byte)RopId.RopQueryRows, LogonId = TestSuiteBase.LogonId, InputHandleIndex = TestSuiteBase.InputHandleIndex0, RowCount = (ushort)rowCount, QueryRowsFlags = (byte)QueryRowsFlags.Advance, ForwardRead = 0x01 }; this.responseSOHs = this.cropsAdapter.ProcessSingleRop( queryRowsRequest, tableHandle, ref this.response, ref this.rawData, RopResponseType.SuccessResponse); RopQueryRowsResponse queryRowsResponse = (RopQueryRowsResponse)this.response; Site.Assert.AreEqual<uint>( TestSuiteBase.SuccessReturnValue, queryRowsResponse.ReturnValue, "if ROP succeeds, the ReturnValue of its response is 0(success)"); #endregion return queryRowsResponse.RowData.PropertyRows; }
/// <summary> /// Query the rows of specific table. /// </summary> /// <param name="objHandle">The handle of specific table.</param> /// <returns>The response of RopQueryRows.</returns> protected RopQueryRowsResponse QueryRowsSuccess(uint objHandle) { 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, objHandle, ref this.response, ref this.rawData, GetPropertiesFlags.None); RopQueryRowsResponse queryRowsResponse = (RopQueryRowsResponse)this.response; Site.Assert.AreEqual<uint>(TestSuiteBase.Success, queryRowsResponse.ReturnValue, TestSuiteBase.ROPSucceedMsg); return queryRowsResponse; }