public void MSOXCFOLD_S03_TC16_GetPropertyPidTagFolderFlags() { this.CheckWhetherSupportTransport(); this.Adapter.DoConnect(ConnectionType.PrivateMailboxServer); this.GenericFolderInitialization(); #region Step 1. Call RopCreateFolder to create [MSOXCFOLDSubfolder1] under the root folder. uint subfolderHandle1 = 0; ulong subfolderId1 = 0; this.CreateFolder(this.RootFolderHandle, Constants.Subfolder1, ref subfolderId1, ref subfolderHandle1); #endregion #region Step 2. Creates a none-FAI message in [MSOXCFOLDSubfolder1]. ulong messageId = 0; uint messageHandle = 0; this.CreateSaveMessage(subfolderHandle1, subfolderId1, ref messageId, ref messageHandle); #endregion #region Step 3. Create a FAI message and saves it in [MSOXCFOLDSubfolder1]. uint messageHandle2 = 0; ulong messageId2 = 0; this.CreateSaveMessage(subfolderHandle1, subfolderId1, 0x01, ref messageId2, ref messageHandle2); #endregion #region Step 4. The client calls RopCreateFolder to create the search folder [MSOXCFOLDSearchFolder1] under the root folder. RopCreateFolderRequest createFolderRequest = new RopCreateFolderRequest { RopId = (byte)RopId.RopCreateFolder, LogonId = Constants.CommonLogonId, InputHandleIndex = Constants.CommonInputHandleIndex, OutputHandleIndex = Constants.CommonOutputHandleIndex, FolderType = (byte)FolderType.Searchfolder, UseUnicodeStrings = 0x0, OpenExisting = 0x00, Reserved = 0x0, DisplayName = Encoding.ASCII.GetBytes(Constants.SearchFolder), Comment = Encoding.ASCII.GetBytes(Constants.SearchFolder) }; RopCreateFolderResponse createFolderResponse = this.Adapter.CreateFolder(createFolderRequest, this.RootFolderHandle, ref this.responseHandles); Site.Assert.AreEqual<uint>(Constants.SuccessCode, createFolderResponse.ReturnValue, "RopCreateFolder ROP operation performs successfully!"); uint searchFolderHandle = this.responseHandles[0][createFolderResponse.OutputHandleIndex]; #endregion #region Step 5. The client calls RopSetSearchCriteria to establish search criteria for [MSOXCFOLDSearchFolder1]. RopSetSearchCriteriaRequest setSearchCriteriaRequest = new RopSetSearchCriteriaRequest { RopId = (byte)RopId.RopSetSearchCriteria, LogonId = Constants.CommonLogonId, InputHandleIndex = Constants.CommonInputHandleIndex }; PropertyTag propertyTag = new PropertyTag { PropertyId = (ushort)MessagePropertyId.PidTagMessageClass, PropertyType = (ushort)PropertyType.PtypString }; ExistRestriction existRestriction = new ExistRestriction { PropTag = propertyTag }; setSearchCriteriaRequest.RestrictionDataSize = (ushort)existRestriction.Size(); setSearchCriteriaRequest.RestrictionData = existRestriction.Serialize(); setSearchCriteriaRequest.FolderIds = new ulong[] { subfolderId1 }; setSearchCriteriaRequest.FolderIdCount = (ushort)setSearchCriteriaRequest.FolderIds.Length; setSearchCriteriaRequest.SearchFlags = (uint)SetSearchFlags.NonContentIndexedSearch | (uint)SetSearchFlags.RestartSearch; RopSetSearchCriteriaResponse setSearchCriteriaResponse = this.Adapter.SetSearchCriteria(setSearchCriteriaRequest, searchFolderHandle, ref this.responseHandles); Site.Assert.AreEqual<uint>(Constants.SuccessCode, setSearchCriteriaResponse.ReturnValue, "RopSearchCriteria ROP operation performs successfully!"); #endregion #region Step 6. The client calls RopGetContentsTable to retrieve the contents table for the search folder [MSOXCFOLDSearchFolder1]. RopGetContentsTableRequest getContentsTableRequest = new RopGetContentsTableRequest(); RopGetContentsTableResponse getContentsTableResponse; getContentsTableRequest.RopId = (byte)RopId.RopGetContentsTable; getContentsTableRequest.LogonId = Constants.CommonLogonId; getContentsTableRequest.InputHandleIndex = Constants.CommonInputHandleIndex; getContentsTableRequest.OutputHandleIndex = Constants.CommonOutputHandleIndex; getContentsTableRequest.TableFlags = (byte)FolderTableFlags.None; int count = 0; do { getContentsTableResponse = this.Adapter.GetContentsTable(getContentsTableRequest, searchFolderHandle, ref this.responseHandles); Site.Assert.AreEqual<uint>(Constants.SuccessCode, getContentsTableResponse.ReturnValue, "RopGetContentsTable ROP operation performs successfully!"); if (getContentsTableResponse.RowCount != 1) { Thread.Sleep(this.WaitTime); } else { break; } count++; } while (count < this.RetryCount); #endregion #region Step 7. The client creates rules on [MSOXCFOLDSubfolder1] folder. RuleData[] sampleRuleDataArray; object ropResponse = null; sampleRuleDataArray = this.CreateSampleRuleDataArrayForAdd(); RopModifyRulesRequest modifyRulesRequest = new RopModifyRulesRequest() { RopId = (byte)RopId.RopModifyRules, LogonId = Constants.CommonLogonId, InputHandleIndex = Constants.CommonInputHandleIndex, ModifyRulesFlags = 0x00, RulesCount = (ushort)sampleRuleDataArray.Length, RulesData = sampleRuleDataArray, }; modifyRulesRequest.RopId = (byte)RopId.RopModifyRules; modifyRulesRequest.LogonId = Constants.CommonLogonId; modifyRulesRequest.InputHandleIndex = Constants.CommonInputHandleIndex; sampleRuleDataArray = this.CreateSampleRuleDataArrayForAdd(); modifyRulesRequest.ModifyRulesFlags = 0x00; modifyRulesRequest.RulesCount = (ushort)sampleRuleDataArray.Length; modifyRulesRequest.RulesData = sampleRuleDataArray; this.Adapter.DoRopCall(modifyRulesRequest, subfolderHandle1, ref ropResponse, ref this.responseHandles); RopModifyRulesResponse modifyRulesResponse = (RopModifyRulesResponse)ropResponse; Site.Assert.AreEqual<uint>(Constants.SuccessCode, modifyRulesResponse.ReturnValue, "RopModifyRules ROP operation performs successfully!"); #endregion #region Step 8. The client calls RopOpenFolder to open [MSOXCFOLDSubfolder1] folder. RopOpenFolderRequest openFolderRequest = new RopOpenFolderRequest { RopId = (byte)RopId.RopOpenFolder, LogonId = Constants.CommonLogonId, InputHandleIndex = Constants.CommonInputHandleIndex, OutputHandleIndex = Constants.CommonOutputHandleIndex, FolderId = subfolderId1, OpenModeFlags = (byte)FolderOpenModeFlags.None }; RopOpenFolderResponse openFolderResponse = this.Adapter.OpenFolder(openFolderRequest, subfolderHandle1, ref this.responseHandles); Site.Assert.AreEqual<uint>(Constants.SuccessCode, openFolderResponse.ReturnValue, "RopOpenFolder ROP operation performs successfully!"); #endregion #region Step 9. The client gets the PidTagFolderFlags propertie from [MSOXCFOLDSubfolder1]. PropertyTag[] propertyTagArray = new PropertyTag[1]; propertyTag = new PropertyTag { PropertyId = (ushort)FolderPropertyId.PidTagFolderFlags, PropertyType = (ushort)PropertyType.PtypInteger32 }; propertyTagArray[0] = propertyTag; RopGetPropertiesSpecificRequest getPropertiesSpecificRequest = new RopGetPropertiesSpecificRequest(); RopGetPropertiesSpecificResponse getPropertiesSpecificResponse; getPropertiesSpecificRequest.RopId = (byte)RopId.RopGetPropertiesSpecific; getPropertiesSpecificRequest.LogonId = Constants.CommonLogonId; getPropertiesSpecificRequest.InputHandleIndex = Constants.CommonInputHandleIndex; getPropertiesSpecificRequest.PropertySizeLimit = 0xFFFF; getPropertiesSpecificRequest.PropertyTagCount = (ushort)propertyTagArray.Length; getPropertiesSpecificRequest.PropertyTags = propertyTagArray; getPropertiesSpecificResponse = this.Adapter.GetFolderObjectSpecificProperties(getPropertiesSpecificRequest, subfolderHandle1, ref this.responseHandles); Site.Assert.AreEqual<uint>(0, getPropertiesSpecificResponse.ReturnValue, "RopGetPropertiesSpecific ROP operation performs successfully!"); uint pidTagFolderFlags = BitConverter.ToUInt32(getPropertiesSpecificResponse.RowData.PropertyValues[0].Value, 0); #region Verify MS-OXCFOLD_R1035110, MS-OXCFOLD_R1035111, MS-OXCFOLD_R1035103 and MS-OXCFOLD_R1035107 // Add the debug information Site.Log.Add(LogEntryKind.Debug, @"Verify MS-OXCFOLD_R1035110: [In PidTagFolderFlags Property] The PidTagFolderId property ([MS-OXPROPS] section 2.692) contains a computed value that specifies the type or state of a folder."); // Verify MS-OXCFOLD requirement: MS-OXCFOLD_R1035110 Site.CaptureRequirement( 1035110, @"[In PidTagFolderFlags Property] The PidTagFolderId property ([MS-OXPROPS] section 2.692) contains a computed value that specifies the type or state of a folder."); // Add the debug information Site.Log.Add(LogEntryKind.Debug, @"Verify MS-OXCFOLD_R1035111: [In PidTagFolderFlags Property] The value is a bitwise OR of zero or more values [1: IPM, 2: SEARCH, 4: NORMAL, 8: RULES] from the following table."); bool isR1035111Verified = false; if (((pidTagFolderFlags & 1) == 1) || ((pidTagFolderFlags & 2) == 2) || ((pidTagFolderFlags & 4) == 4) || ((pidTagFolderFlags & 8) == 8)) { isR1035111Verified = true; } // Verify MS-OXCFOLD requirement: MS-OXCFOLD_R1035111 Site.CaptureRequirementIfIsTrue( isR1035111Verified, 1035111, @"[In PidTagFolderFlags Property] The value is a bitwise OR of zero or more values [1: IPM, 2: SEARCH, 4: NORMAL, 8: RULES] from the following table."); // Add the debug information Site.Log.Add(LogEntryKind.Debug, @"Verify MS-OXCFOLD_R1035103: [In PidTagFolderFlags Property] [The folder flag named ""IPM"" specified] the folder belongs to the IPM subtree portion of the mailbox."); bool isR1035103Verified = false; if ((pidTagFolderFlags & 1) == 1) { isR1035103Verified = true; } // Verify MS-OXCFOLD requirement: MS-OXCFOLD_R1035103 Site.CaptureRequirementIfIsTrue( isR1035103Verified, 1035103, @"[In PidTagFolderFlags Property] [The folder flag named ""IPM"" specified] the folder belongs to the IPM subtree portion of the mailbox."); // Add the debug information Site.Log.Add(LogEntryKind.Debug, @"Verify MS-OXCFOLD_R1035107: [In PidTagFolderFlags Property] [The folder flag named ""NORMAL"" specified] the folder is a generic folder that contains messages and other folders."); bool isR1035107Verified = false; if ((pidTagFolderFlags & 4) == 4) { isR1035107Verified = true; } // Verify MS-OXCFOLD requirement: MS-OXCFOLD_R1035107 Site.CaptureRequirementIfIsTrue( isR1035107Verified, 1035107, @"[In PidTagFolderFlags Property] [The folder flag named ""NORMAL"" specified] the folder is a generic folder that contains messages and other folders."); #endregion #endregion }
public void MSOXCFOLD_S03_TC14_ContentIndexedSearchVerification() { this.CheckWhetherSupportTransport(); this.Adapter.DoConnect(ConnectionType.PrivateMailboxServer); this.GenericFolderInitialization(); #region Step 1. The client calls RopCreateFolder to create the general folder [MSOXCFOLDSubfolder1] under the root folder. RopCreateFolderRequest createFolderRequest = new RopCreateFolderRequest { RopId = (byte)RopId.RopCreateFolder, LogonId = Constants.CommonLogonId, InputHandleIndex = Constants.CommonInputHandleIndex, OutputHandleIndex = Constants.CommonOutputHandleIndex, FolderType = (byte)FolderType.Genericfolder, UseUnicodeStrings = 0x0, OpenExisting = 0x00, Reserved = 0x0, DisplayName = Encoding.ASCII.GetBytes(Constants.Subfolder1), Comment = Encoding.ASCII.GetBytes(Constants.Subfolder1) }; RopCreateFolderResponse createFolderResponse = this.Adapter.CreateFolder(createFolderRequest, this.RootFolderHandle, ref this.responseHandles); Site.Assert.AreEqual<uint>(Constants.SuccessCode, createFolderResponse.ReturnValue, "RopCreateFolder ROP operation performs successfully!"); uint subfolderHandle1 = this.responseHandles[0][createFolderResponse.OutputHandleIndex]; ulong subfolderId1 = createFolderResponse.FolderId; #endregion #region Step 2. The client creates a non-FAI message under the general folder [MSOXCFOLDSubfolder1]. uint messageNonFAIHandle1 = 0; ulong messageNonFAIId1 = 0; this.CreateSaveMessage(subfolderHandle1, subfolderId1, ref messageNonFAIId1, ref messageNonFAIHandle1); #endregion #region Step 3. The client calls RopCreateFolder to create the general folder [MSOXCFOLDSubfolder2] under the general folder [MSOXCFOLDSubfolder1]. createFolderRequest.FolderType = (byte)FolderType.Genericfolder; createFolderRequest.DisplayName = Encoding.ASCII.GetBytes(Constants.Subfolder2); createFolderRequest.Comment = Encoding.ASCII.GetBytes(Constants.Subfolder2); createFolderResponse = this.Adapter.CreateFolder(createFolderRequest, subfolderHandle1, ref this.responseHandles); Site.Assert.AreEqual<uint>(Constants.SuccessCode, createFolderResponse.ReturnValue, "RopCreateFolder ROP operation performs successfully!"); uint subfolderHandle2 = this.responseHandles[0][createFolderResponse.OutputHandleIndex]; ulong subfolderId2 = createFolderResponse.FolderId; #endregion #region Step 4. The client creates a non-FAI message under the general folder [MSOXCFOLDSubfolder2]. uint messageNonFAIHandle2 = 0; ulong messageNonFAIId2 = 0; this.CreateSaveMessage(subfolderHandle2, subfolderId2, ref messageNonFAIId2, ref messageNonFAIHandle2); #endregion #region Step 5. The client calls RopCreateFolder to create the search folder [MSOXCFOLDSearchFolder1] under the root folder. createFolderRequest.FolderType = (byte)FolderType.Searchfolder; createFolderRequest.DisplayName = Encoding.ASCII.GetBytes(Constants.SearchFolder); createFolderRequest.Comment = Encoding.ASCII.GetBytes(Constants.SearchFolder); createFolderResponse = this.Adapter.CreateFolder(createFolderRequest, this.RootFolderHandle, ref this.responseHandles); Site.Assert.AreEqual<uint>(Constants.SuccessCode, createFolderResponse.ReturnValue, "RopCreateFolder ROP operation performs successfully!"); uint searchFolderHandle1 = this.responseHandles[0][createFolderResponse.OutputHandleIndex]; #endregion #region Step 6. The client calls RopSetSearchCriteria to establish search criteria for [MSOXCFOLDSearchFolder1]. RopSetSearchCriteriaRequest setSearchCriteriaRequest = new RopSetSearchCriteriaRequest { RopId = (byte)RopId.RopSetSearchCriteria, LogonId = Constants.CommonLogonId, InputHandleIndex = Constants.CommonInputHandleIndex }; PropertyTag propertyTag = new PropertyTag { PropertyId = (ushort)MessagePropertyId.PidTagMessageClass, PropertyType = (ushort)PropertyType.PtypString }; ExistRestriction existRestriction = new ExistRestriction { PropTag = propertyTag }; setSearchCriteriaRequest.RestrictionDataSize = (ushort)existRestriction.Size(); setSearchCriteriaRequest.RestrictionData = existRestriction.Serialize(); setSearchCriteriaRequest.FolderIds = new ulong[] { subfolderId1 }; setSearchCriteriaRequest.FolderIdCount = (ushort)setSearchCriteriaRequest.FolderIds.Length; setSearchCriteriaRequest.SearchFlags = (uint)SetSearchFlags.ContentIndexedSearch | (uint)SetSearchFlags.RestartSearch | (uint)SetSearchFlags.ForGroundSearch | (uint)SetSearchFlags.RecursiveSearch; RopSetSearchCriteriaResponse setSearchCriteriaResponse = this.Adapter.SetSearchCriteria(setSearchCriteriaRequest, searchFolderHandle1, ref this.responseHandles); Site.Assert.AreEqual<uint>(Constants.SuccessCode, setSearchCriteriaResponse.ReturnValue, "RopSearchCriteria ROP operation performs successfully!"); // Add the debug information Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCFOLD_R782"); // Verify MS-OXCFOLD requirement: MS-OXCFOLD_R782 Site.CaptureRequirementIfAreEqual<uint>( Constants.SuccessCode, setSearchCriteriaResponse.ReturnValue, 782, @"[In RopSetSearchCriteria ROP Request Buffer] SearchFlags (4 bytes): CONTENT_INDEXED_SEARCH (0x00010000) means that the search uses a content-indexed search."); #endregion #region Step 7. The client calls RopGetSearchCriteria to obtain the search criteria and the status of the search folder [MSOXCFOLDSearchFolder1]. RopGetSearchCriteriaRequest getSearchCriteriaRequest = new RopGetSearchCriteriaRequest { RopId = (byte)RopId.RopGetSearchCriteria, LogonId = Constants.CommonLogonId, InputHandleIndex = Constants.CommonInputHandleIndex, UseUnicode = 0x00, IncludeRestriction = 0x01, IncludeFolders = 0x01 }; RopGetSearchCriteriaResponse getSearchCriteriaResponse = this.Adapter.GetSearchCriteria(getSearchCriteriaRequest, searchFolderHandle1, ref this.responseHandles); Site.Assert.AreEqual<uint>(Constants.SuccessCode, getSearchCriteriaResponse.ReturnValue, "RopGetSearchCriteria ROP operation performs successfully!"); ulong priviewFolderId = getSearchCriteriaResponse.FolderIds[0]; #endregion #region Step 8. The client calls RopGetContentsTable to retrieve the contents table for the search folder [MSOXCFOLDSearchFolder1]. RopGetContentsTableRequest getContentsTableRequest = new RopGetContentsTableRequest(); RopGetContentsTableResponse getContentsTableResponse; getContentsTableRequest.RopId = (byte)RopId.RopGetContentsTable; getContentsTableRequest.LogonId = Constants.CommonLogonId; getContentsTableRequest.InputHandleIndex = Constants.CommonInputHandleIndex; getContentsTableRequest.OutputHandleIndex = Constants.CommonOutputHandleIndex; getContentsTableRequest.TableFlags = (byte)FolderTableFlags.None; int count = 0; do { getContentsTableResponse = this.Adapter.GetContentsTable(getContentsTableRequest, searchFolderHandle1, ref this.responseHandles); Site.Assert.AreEqual<uint>(Constants.SuccessCode, getContentsTableResponse.ReturnValue, "RopGetContentsTable ROP operation performs successfully!"); if (getContentsTableResponse.RowCount != 2) { Thread.Sleep(this.WaitTime); } else { break; } count++; } while (count < this.RetryCount); #region Verify the requirements: MS-OXCFOLD_R515, MS-OXCFOLD_R770, and MS-OXCFOLD_R789. // Add the debug information Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCFOLD_R515"); // Verify MS-OXCFOLD requirement: MS-OXCFOLD_R515 // There has 2 messages matched the search criteria, so the RowCount should be 2. Site.CaptureRequirementIfAreEqual<uint>( 2, getContentsTableResponse.RowCount, 515, @"[In Processing a RopSetSearchCriteria ROP Request] The server fills the search folder according to the search criteria and search scope that are specified in the RopSetSearchCriteria ROP request."); // Add the debug information Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCFOLD_R770"); // Verify MS-OXCFOLD requirement: MS-OXCFOLD_R770 Site.CaptureRequirementIfAreEqual<uint>( 2, getContentsTableResponse.RowCount, 770, @"[In RopSetSearchCriteria ROP Request Buffer]SearchFlags (4 bytes): RECURSIVE_SEARCH (0x00000004) means that the search includes the search folder containers and all of their child folders."); // Add the debug information Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCFOLD_R789"); // Verify MS-OXCFOLD requirement: MS-OXCFOLD_R789 // There has 2 messages matched search criteria, so the RowCount should be 2. Site.CaptureRequirementIfAreEqual<uint>( 2, getContentsTableResponse.RowCount, 789, @"[In RopGetSearchCriteria ROP Response Buffer] SearchFlags (4 bytes): If this bit [SEARCH_RECURSIVE (0x00000004)] is set, the specified search folder containers and all their child search folder containers are searched for matching entries."); #endregion #endregion #region Step 9. The client creates a non-FAI message under the general folder [MSOXCFOLDSubfolder1]. uint messageNonFAIHandle3 = 0; ulong messageNonFAIId3 = 0; this.CreateSaveMessage(subfolderHandle1, subfolderId1, ref messageNonFAIId3, ref messageNonFAIHandle3); #endregion #region Step 10. The client calls RopSetSearchCriteria without setting the SearchFlags field to establish search criteria for [MSOXCFOLDSearchFolder1]. setSearchCriteriaRequest.FolderIdCount = 0; setSearchCriteriaRequest.FolderIds = null; setSearchCriteriaRequest.SearchFlags = (uint)SetSearchFlags.None; setSearchCriteriaResponse = this.Adapter.SetSearchCriteria(setSearchCriteriaRequest, searchFolderHandle1, ref this.responseHandles); Site.Assert.AreEqual<uint>(Constants.SuccessCode, setSearchCriteriaResponse.ReturnValue, "RopSearchCriteria ROP operation performs successfully!"); #endregion #region Step 11. The client calls RopGetSearchCriteria to obtain the search criteria and the status of the search folder [MSOXCFOLDSearchFolder1]. getSearchCriteriaResponse = this.Adapter.GetSearchCriteria(getSearchCriteriaRequest, searchFolderHandle1, ref this.responseHandles); Site.Assert.AreEqual<uint>(Constants.SuccessCode, getSearchCriteriaResponse.ReturnValue, "RopGetSearchCriteria ROP operation performs successfully!"); // Add the debug information Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCFOLD_R109"); // Verify MS-OXCFOLD requirement: MS-OXCFOLD_R109 Site.CaptureRequirementIfAreEqual<ulong>( priviewFolderId, getSearchCriteriaResponse.FolderIds[0], 109, @"[In RopSetSearchCriteria ROP Request Buffer] FolderIdCount (2 bytes): If the FolderIdCount field is set to zero, the folders that were used in the most recent search are used again."); #endregion #region Step 12. The client calls RopCreateFolder to create the search folder [MSOXCFOLDSearchFolder2] under the root folder. createFolderRequest.FolderType = (byte)FolderType.Searchfolder; createFolderRequest.DisplayName = Encoding.ASCII.GetBytes(Constants.SearchFolder2); createFolderRequest.Comment = Encoding.ASCII.GetBytes(Constants.SearchFolder2); createFolderResponse = this.Adapter.CreateFolder(createFolderRequest, this.RootFolderHandle, ref this.responseHandles); Site.Assert.AreEqual<uint>(Constants.SuccessCode, createFolderResponse.ReturnValue, "RopCreateFolder ROP operation performs successfully!"); uint searchFolderHandle2 = this.responseHandles[0][createFolderResponse.OutputHandleIndex]; #endregion #region Step 13. The client calls RopSetSearchCriteria to establish search criteria for [MSOXCFOLDSearchFolder2]. setSearchCriteriaRequest = new RopSetSearchCriteriaRequest { RopId = (byte)RopId.RopSetSearchCriteria, LogonId = Constants.CommonLogonId, InputHandleIndex = Constants.CommonInputHandleIndex }; propertyTag = new PropertyTag { PropertyId = (ushort)MessagePropertyId.PidTagMessageClass, PropertyType = (ushort)PropertyType.PtypString }; existRestriction = new ExistRestriction { PropTag = propertyTag }; setSearchCriteriaRequest.RestrictionDataSize = (ushort)existRestriction.Size(); setSearchCriteriaRequest.RestrictionData = existRestriction.Serialize(); setSearchCriteriaRequest.FolderIds = new ulong[] { subfolderId1 }; setSearchCriteriaRequest.FolderIdCount = (ushort)setSearchCriteriaRequest.FolderIds.Length; setSearchCriteriaRequest.SearchFlags = (uint)SetSearchFlags.ContentIndexedSearch | (uint)SetSearchFlags.RestartSearch; setSearchCriteriaResponse = this.Adapter.SetSearchCriteria(setSearchCriteriaRequest, searchFolderHandle2, ref this.responseHandles); Site.Assert.AreEqual<uint>(Constants.SuccessCode, setSearchCriteriaResponse.ReturnValue, "RopSearchCriteria ROP operation performs successfully!"); #endregion #region Step 14. The client calls RopGetSearchCriteria to obtain the search criteria and the status of the search folder [MSOXCFOLDSearchFolder2]. getSearchCriteriaResponse = this.Adapter.GetSearchCriteria(getSearchCriteriaRequest, searchFolderHandle2, ref this.responseHandles); Site.Assert.AreEqual<uint>(Constants.SuccessCode, getSearchCriteriaResponse.ReturnValue, "RopGetSearchCriteria ROP operation performs successfully!"); #endregion #region Step 15. The client calls RopGetContentsTable to retrieve the contents table for the search folder [MSOXCFOLDSearchFolder2]. count = 0; do { getContentsTableResponse = this.Adapter.GetContentsTable(getContentsTableRequest, searchFolderHandle2, ref this.responseHandles); Site.Assert.AreEqual<uint>(Constants.SuccessCode, getContentsTableResponse.ReturnValue, "RopGetContentsTable ROP operation performs successfully!"); if (getContentsTableResponse.RowCount != 2) { Thread.Sleep(this.WaitTime); } else { break; } count++; } while (count < this.RetryCount); // Add the debug information Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCFOLD_R960"); // Verify MS-OXCFOLD requirement: MS-OXCFOLD_R960 // There has 2 messages matched the search criteria, so the RowCount should be 2. Site.CaptureRequirementIfAreEqual<uint>( 2, getContentsTableResponse.RowCount, 960, @"[In RopGetSearchCriteria ROP Response Buffer] If this bit [SEARCH_RECURSIVE] is not set, only the search folder containers that are specified in the last RopSetSearchCriteria ROP request (section 2.2.1.4.1) are being searched."); #endregion }
public void MSOXCFOLD_S03_TC15_NonContentIndexedSearchVerification() { this.CheckWhetherSupportTransport(); this.Adapter.DoConnect(ConnectionType.PrivateMailboxServer); this.GenericFolderInitialization(); #region Step 1. The client calls RopCreateFolder to create the general folder [MSOXCFOLDSubfolder1] under the root folder. RopCreateFolderRequest createFolderRequest = new RopCreateFolderRequest { RopId = (byte)RopId.RopCreateFolder, LogonId = Constants.CommonLogonId, InputHandleIndex = Constants.CommonInputHandleIndex, OutputHandleIndex = Constants.CommonOutputHandleIndex, FolderType = 0x01, UseUnicodeStrings = 0x0, OpenExisting = 0x00, Reserved = 0x0, DisplayName = Encoding.ASCII.GetBytes(Constants.Subfolder1), Comment = Encoding.ASCII.GetBytes(Constants.Subfolder1) }; RopCreateFolderResponse createFolderResponse = this.Adapter.CreateFolder(createFolderRequest, this.RootFolderHandle, ref this.responseHandles); Site.Assert.AreEqual<uint>(Constants.SuccessCode, createFolderResponse.ReturnValue, "RopCreateFolder ROP operation performs successfully!"); uint subfolderHandle1 = this.responseHandles[0][createFolderResponse.OutputHandleIndex]; ulong subfolderId1 = createFolderResponse.FolderId; #endregion #region Step 2. The client creates a non-FAI message under the general folder [MSOXCFOLDSubfolder1]. uint messageNonFAIHandle1 = 0; ulong messageNonFAIId1 = 0; this.CreateSaveMessage(subfolderHandle1, subfolderId1, ref messageNonFAIId1, ref messageNonFAIHandle1); #endregion #region Step 3. The client calls RopCreateFolder to create the search folder [MSOXCFOLDSearchFolder1] under the root folder. createFolderRequest.FolderType = (byte)FolderType.Searchfolder; createFolderRequest.DisplayName = Encoding.ASCII.GetBytes(Constants.SearchFolder); createFolderRequest.Comment = Encoding.ASCII.GetBytes(Constants.SearchFolder); createFolderResponse = this.Adapter.CreateFolder(createFolderRequest, this.RootFolderHandle, ref this.responseHandles); Site.Assert.AreEqual<uint>(Constants.SuccessCode, createFolderResponse.ReturnValue, "RopCreateFolder ROP operation performs successfully!"); uint searchFolderHandle = this.responseHandles[0][createFolderResponse.OutputHandleIndex]; #endregion #region Step 4. The client calls RopSetSearchCriteria to establish search criteria for [MSOXCFOLDSearchFolder1]. RopSetSearchCriteriaRequest setSearchCriteriaRequest = new RopSetSearchCriteriaRequest { RopId = (byte)RopId.RopSetSearchCriteria, LogonId = Constants.CommonLogonId, InputHandleIndex = Constants.CommonInputHandleIndex }; PropertyTag propertyTag = new PropertyTag { PropertyId = (ushort)MessagePropertyId.PidTagMessageClass, PropertyType = (ushort)PropertyType.PtypString }; ExistRestriction existRestriction = new ExistRestriction { PropTag = propertyTag }; setSearchCriteriaRequest.RestrictionDataSize = (ushort)existRestriction.Size(); setSearchCriteriaRequest.RestrictionData = existRestriction.Serialize(); setSearchCriteriaRequest.FolderIds = new ulong[] { subfolderId1 }; setSearchCriteriaRequest.FolderIdCount = (ushort)setSearchCriteriaRequest.FolderIds.Length; setSearchCriteriaRequest.SearchFlags = (uint)SetSearchFlags.NonContentIndexedSearch | (uint)SetSearchFlags.RestartSearch; RopSetSearchCriteriaResponse setSearchCriteriaResponse = this.Adapter.SetSearchCriteria(setSearchCriteriaRequest, searchFolderHandle, ref this.responseHandles); Site.Assert.AreEqual<uint>(Constants.SuccessCode, setSearchCriteriaResponse.ReturnValue, "RopSearchCriteria ROP operation performs successfully!"); // Add the debug information Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCFOLD_R783"); // Verify MS-OXCFOLD requirement: MS-OXCFOLD_R783 Site.CaptureRequirementIfAreEqual<uint>( Constants.SuccessCode, setSearchCriteriaResponse.ReturnValue, 783, @"[In RopSetSearchCriteria ROP Request Buffer] SearchFlags (4 bytes): NON_CONTENT_INDEXED_SEARCH (0x00020000) means that the search does not use a content-indexed search."); #endregion #region Step 5. The client calls RopGetContentsTable to retrieve the contents table for the search folder [MSOXCFOLDSearchFolder1]. RopGetContentsTableRequest getContentsTableRequest = new RopGetContentsTableRequest(); RopGetContentsTableResponse getContentsTableResponse; getContentsTableRequest.RopId = (byte)RopId.RopGetContentsTable; getContentsTableRequest.LogonId = Constants.CommonLogonId; getContentsTableRequest.InputHandleIndex = Constants.CommonInputHandleIndex; getContentsTableRequest.OutputHandleIndex = Constants.CommonOutputHandleIndex; getContentsTableRequest.TableFlags = (byte)FolderTableFlags.None; int count = 0; do { getContentsTableResponse = this.Adapter.GetContentsTable(getContentsTableRequest, searchFolderHandle, ref this.responseHandles); Site.Assert.AreEqual<uint>(Constants.SuccessCode, getContentsTableResponse.ReturnValue, "RopGetContentsTable ROP operation performs successfully!"); if (getContentsTableResponse.RowCount != 1) { Thread.Sleep(this.WaitTime); } else { break; } count++; } while (count < this.RetryCount); #endregion #region Step 6. The client calls RopSetSearchCriteria to stop establish search criteria for [MSOXCFOLDSearchFolder1]. setSearchCriteriaRequest.SearchFlags = (uint)SetSearchFlags.StopSearch; setSearchCriteriaResponse = this.Adapter.SetSearchCriteria(setSearchCriteriaRequest, searchFolderHandle, ref this.responseHandles); Site.Assert.AreEqual<uint>(Constants.SuccessCode, setSearchCriteriaResponse.ReturnValue, "RopSearchCriteria ROP operation performs successfully!"); #endregion #region Step 7. The client calls RopGetSearchCriteria to obtain the search criteria and the status of the search folder [MSOXCFOLDSearchFolder1]. RopGetSearchCriteriaRequest getSearchCriteriaRequest = new RopGetSearchCriteriaRequest { RopId = (byte)RopId.RopGetSearchCriteria, LogonId = Constants.CommonLogonId, InputHandleIndex = Constants.CommonInputHandleIndex, UseUnicode = 0x00, IncludeRestriction = 0x01, IncludeFolders = 0x01 }; RopGetSearchCriteriaResponse getSearchCriteriaResponse = this.Adapter.GetSearchCriteria(getSearchCriteriaRequest, searchFolderHandle, ref this.responseHandles); Site.Assert.AreEqual<uint>(Constants.SuccessCode, getSearchCriteriaResponse.ReturnValue, "RopGetSearchCriteria ROP operation performs successfully!"); #region Verify the requirements: MS-OXCFOLD_R673, MS-OXCFOLD_R54301. // Add the debug information Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCFOLD_R673"); // Verify MS-OXCFOLD requirement: MS-OXCFOLD_R673 Site.CaptureRequirementIfAreNotEqual<uint>( (uint)GetSearchFlags.Running, getSearchCriteriaResponse.SearchFlags & (uint)GetSearchFlags.Running, 673, @"[In RopSetSearchCriteria ROP Request Buffer] SearchFlags (4 bytes):STOP_SEARCH (0x00000001) means that the search is aborted."); if (Common.IsRequirementEnabled(54301, this.Site)) { // Add the debug information Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCFOLD_R54301"); // Verify MS-OXCFOLD requirement: MS-OXCFOLD_R54301 Site.CaptureRequirementIfAreNotEqual<uint>( (uint)GetSearchFlags.Running, getSearchCriteriaResponse.SearchFlags & (uint)GetSearchFlags.Running, 54301, @"[In Processing a RopSetSearchCriteria ROP Request] Implementation does stop the initial population of the search folder if the STOP_SEARCH bit is set in the SearchFlags field. (Exchange 2007 and above follow this behavior)."); } #endregion #endregion #region Step 8. The client calls RopSetSearchCriteria to restart establish search criteria for [MSOXCFOLDSearchFolder1]. setSearchCriteriaRequest.SearchFlags = (uint)SetSearchFlags.RestartSearch; setSearchCriteriaResponse = this.Adapter.SetSearchCriteria(setSearchCriteriaRequest, searchFolderHandle, ref this.responseHandles); Site.Assert.AreEqual<uint>(Constants.SuccessCode, setSearchCriteriaResponse.ReturnValue, "RopSearchCriteria ROP operation performs successfully!"); #endregion #region Step 9. The client calls RopGetSearchCriteria to obtain the search criteria and the status of the search folder [MSOXCFOLDSearchFolder1]. getSearchCriteriaResponse = this.Adapter.GetSearchCriteria(getSearchCriteriaRequest, searchFolderHandle, ref this.responseHandles); Site.Assert.AreEqual<uint>(Constants.SuccessCode, getSearchCriteriaResponse.ReturnValue, "RopGetSearchCriteria ROP operation performs successfully!"); Site.Assert.AreEqual<uint>((uint)GetSearchFlags.Running, getSearchCriteriaResponse.SearchFlags & (uint)GetSearchFlags.Running, "The SearchFlags field contains the 'SEARCH_RUNNING' bits."); #region Verify the requirements: MS-OXCFOLD_R546, MS-OXCFOLD_R768, and MS-OXCFOLD_R767. // Add the debug information Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCFOLD_R767"); // Verify MS-OXCFOLD requirement: MS-OXCFOLD_R767 Site.CaptureRequirementIfAreEqual<uint>( (uint)GetSearchFlags.Running, getSearchCriteriaResponse.SearchFlags & (uint)GetSearchFlags.Running, 767, @"[In RopSetSearchCriteria ROP Request Buffer] SearchFlags (4 bytes): RESTART_SEARCH (0x00000002) means that the search is initiated, if the search is restarted."); // Add the debug information Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCFOLD_R768"); // Verify MS-OXCFOLD requirement: MS-OXCFOLD_R768 Site.CaptureRequirementIfAreEqual<uint>( (uint)GetSearchFlags.Running, getSearchCriteriaResponse.SearchFlags & (uint)GetSearchFlags.Running, 768, @"[In RopSetSearchCriteria ROP Request Buffer] SearchFlags (4 bytes): RESTART_SEARCH (0x00000002) means that the search is initiated, if the search is inactive."); // Add the debug information Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCFOLD_R546"); // Verify MS-OXCFOLD requirement: MS-OXCFOLD_R546 Site.CaptureRequirementIfAreEqual<uint>( (uint)GetSearchFlags.Running, getSearchCriteriaResponse.SearchFlags & (uint)GetSearchFlags.Running, 546, @"[In Processing a RopSetSearchCriteria ROP Request] If the RESTART_SEARCH bit is set in the SearchFlags field, the server restarts the population of the search folder."); #endregion #endregion }
public void MSOXCFOLD_S03_TC06_RopGetContentsTableSuccess() { this.CheckWhetherSupportTransport(); this.Adapter.DoConnect(ConnectionType.PrivateMailboxServer); this.GenericFolderInitialization(); #region Step 1. The client creates a FAI message in the root folder. uint messageFAIHandle = 0; ulong mesageFAIId = 0; this.CreateSaveMessage(this.RootFolderHandle, this.RootFolderId, 0x01, ref mesageFAIId, ref messageFAIHandle); #endregion #region Step 2. The client creates two non-FAI message in the root folder. uint messageNonFAIHandle1 = 0; ulong mesageNonFAIId1 = 0; this.CreateSaveMessage(this.RootFolderHandle, this.RootFolderId, ref mesageNonFAIId1, ref messageNonFAIHandle1); uint messageNonFAIHandle2 = 0; ulong mesageNonFAIId2 = 0; this.CreateSaveMessage(this.RootFolderHandle, this.RootFolderId, ref mesageNonFAIId2, ref messageNonFAIHandle2); #endregion #region Step 3. The client calls RopGetContentsTable to retrieve the contents table for the root folder without 'Associated' flag. RopGetContentsTableRequest getContentsTableRequest = new RopGetContentsTableRequest { RopId = (byte)RopId.RopGetContentsTable, LogonId = Constants.CommonLogonId, InputHandleIndex = Constants.CommonInputHandleIndex, OutputHandleIndex = Constants.CommonOutputHandleIndex, TableFlags = (byte)FolderTableFlags.None }; RopGetContentsTableResponse getContentsTableResponse = this.Adapter.GetContentsTable(getContentsTableRequest, this.RootFolderHandle, ref this.responseHandles); Site.Assert.AreEqual<uint>(Constants.SuccessCode, getContentsTableResponse.ReturnValue, "RopGetContentsTable ROP operation performs successfully!"); // Add the debug information Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCFOLD_R1167"); // Verify MS-OXCFOLD requirement: MS-OXCFOLD_R1167 // Method GetContentsTable succeeds indicates that the server responds with a RopGetContentsTable ROP response buffer. Site.CaptureRequirement( 1167, @"[In Processing a RopGetContentsTable ROP Request] The server responds with a RopGetContentsTable ROP response buffer."); // Add the debug information Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCFOLD_R1170"); // Verify MS-OXCFOLD requirement: MS-OXCFOLD_R1170 // Method GetContentsTable succeeds indicates that the server returns a contents table on which table operations can be performed. Site.CaptureRequirement( 1170, @"[In Processing a RopGetContentsTable ROP Request] The server returns a contents table on which table operations can be performed."); #region Verify the requirements: MS-OXCFOLD_R663, MS-OXCFOLD_R100502,MS-OXCFOLD_R665 and MS-OXCFOLD_R333. // Add the debug information. Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCFOLD_R100502"); // Verify MS-OXCFOLD requirement: MS-OXCFOLD_R100502. Site.CaptureRequirementIfAreEqual<uint>( Constants.SuccessCode, getContentsTableResponse.ReturnValue, 100502, @"[In RopGetContentsTable ROP] This ROP [RopGetContentsTable] applies to [both public folders and] private mailboxes."); // Add the debug information Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCFOLD_R663"); // Verify MS-OXCFOLD requirement: MS-OXCFOLD_R663 // There has 2 non-FAI messages under the root folder, so the RowCount should be 2. Site.CaptureRequirementIfAreEqual<uint>( 0x00000002, getContentsTableResponse.RowCount, 663, @"[In RopGetContentsTable ROP Request Buffer] If this bit [Associated] is not set, the contents table lists only the non-FAI messages."); // Add the debug information Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCFOLD_R333"); // Verify MS-OXCFOLD requirement: MS-OXCFOLD_R333 // There has 2 messages under the root folder, so the RowCount should be 2. Site.CaptureRequirementIfAreEqual<uint>( 0x00000002, getContentsTableResponse.RowCount, 333, @"[In RopGetContentsTable ROP Response Buffer] RowCount (4 bytes): An integer that specifies the number of rows in the contents table."); // Add debug information. Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCFOLD_R665"); // Verify MS-OXCFOLD requirement: MS-OXCFOLD_R665 // There has only 2 messages existed, so the RowCount should be 2. Site.CaptureRequirementIfAreEqual<uint>( 0x00000002, getContentsTableResponse.RowCount, 665, @"[In RopGetContentsTable ROP Request Buffer]If this bit [SoftDeletes] is not set, the contents table lists only the existing messages."); #endregion #endregion #region Step 4. The client calls RopGetContentsTable to retrieve the contents table for the root folder with 'Associated' flag. getContentsTableRequest.TableFlags = 0x02; getContentsTableResponse = this.Adapter.GetContentsTable(getContentsTableRequest, this.RootFolderHandle, ref this.responseHandles); uint tableHandle = this.responseHandles[0][getContentsTableResponse.OutputHandleIndex]; Site.Assert.AreEqual<uint>(Constants.SuccessCode, getContentsTableResponse.ReturnValue, "RopGetContentsTable ROP operation performs successfully!"); // Add the debug information Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCFOLD_R662"); // Verify MS-OXCFOLD requirement: MS-OXCFOLD_R662 // There has 1 FAI messages contained in the folder, so the RowCount should be 1. Site.CaptureRequirementIfAreEqual<uint>( 0x00000001, getContentsTableResponse.RowCount, 662, @"[In RopGetContentsTable ROP Request Buffer] If this bit [Associated] is set, the contents table lists only the FAI messages."); #endregion #region Step 5. The client calls RopGetContentsTable to retrieve the contents table for the root folder with 'ConversationMembers' flag. getContentsTableRequest.TableFlags = 0x80; getContentsTableResponse = this.Adapter.GetContentsTable(getContentsTableRequest, this.RootFolderHandle, ref this.responseHandles); // Add the debug information Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCFOLD_R10251: the return value of the getContentsTableResponse is {0}", getContentsTableResponse.ReturnValue); // Verify MS-OXCFOLD requirement: MS-OXCFOLD_R10251 // The'ConversationMembers' flag is set in the getContentsTableRequest, so if the getContentsTableResponse returns success. R10251 can be verified. Site.CaptureRequirementIfAreEqual<uint>( 0, getContentsTableResponse.ReturnValue, 10251, @"[In RopGetContentsTable ROP Request Buffer] This bit [ConversationMembers] is supported on the Root folder of a mailbox."); #endregion #region Step 6. Delete one non-FAI message created in step 2 in root folder. object ropResponse = null; ulong[] messageIds = new ulong[] { mesageNonFAIId1 }; RopDeleteMessagesRequest deleteMessagesRequest = new RopDeleteMessagesRequest(); RopDeleteMessagesResponse deleteMessagesResponse; deleteMessagesRequest.RopId = (byte)RopId.RopDeleteMessages; deleteMessagesRequest.LogonId = Constants.CommonLogonId; deleteMessagesRequest.InputHandleIndex = Constants.CommonInputHandleIndex; deleteMessagesRequest.WantAsynchronous = 0x00; // The server does not generate a non-read receipt for the deleted messages. deleteMessagesRequest.NotifyNonRead = 0x00; deleteMessagesRequest.MessageIdCount = (ushort)messageIds.Length; deleteMessagesRequest.MessageIds = messageIds; this.Adapter.DoRopCall(deleteMessagesRequest, this.RootFolderHandle, ref ropResponse, ref this.responseHandles); deleteMessagesResponse = (RopDeleteMessagesResponse)ropResponse; Site.Assert.AreEqual<uint>( 0, deleteMessagesResponse.ReturnValue, "If ROP succeeds, the ReturnValue of its response is 0(success)"); #endregion #region Step 7. The client calls RopGetContentsTable to retrieve the contents table for the root folder with 'Soft-delete' set. if (Common.IsRequirementEnabled(1017, this.Site)) { getContentsTableRequest.TableFlags = 0x20; getContentsTableResponse = this.Adapter.GetContentsTable(getContentsTableRequest, this.RootFolderHandle, ref this.responseHandles); Site.Assert.AreEqual<uint>(Constants.SuccessCode, getContentsTableResponse.ReturnValue, "RopGetContentsTable ROP operation performs successfully!"); // Add the debug information Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCFOLD_R1017: the expected RowCount is {0}, and actually, the RowCount in the getContentsTableResponse is {1}.", 1, getContentsTableResponse.RowCount); // Verify MS-OXCFOLD requirement: MS-OXCFOLD_R1017 // One non-FAI message has been soft-deleted in step 5, so the return count of the getContentsTableResponse should be 1. Site.CaptureRequirementIfAreEqual<uint>( 0x00000001, getContentsTableResponse.RowCount, 1017, @"[In RopGetContentsTable ROP Request Buffer] If this bit [SoftDeletes] is set, the contents table lists only the messages that are soft deleted."); } #endregion #region Step 8. Sets the properties PidTagMid visible on the content table. RopSetColumnsRequest setColumnsRequest; PropertyTag[] propertyTags = new PropertyTag[1]; propertyTags[0].PropertyId = (ushort)MessagePropertyId.PidTagMid; propertyTags[0].PropertyType = (ushort)PropertyType.PtypInteger64; setColumnsRequest.RopId = 0x12; setColumnsRequest.LogonId = 0x00; setColumnsRequest.InputHandleIndex = 0x00; setColumnsRequest.PropertyTagCount = (ushort)propertyTags.Length; setColumnsRequest.PropertyTags = propertyTags; setColumnsRequest.SetColumnsFlags = 0x00; // Sync this.Adapter.DoRopCall(setColumnsRequest, tableHandle, ref ropResponse, ref this.responseHandles); #endregion #region Step 9. Gets the message ID of the message in content table. RopQueryRowsRequest queryRowsRequest; RopQueryRowsResponse queryRowsResponse; queryRowsRequest.RopId = 0x15; queryRowsRequest.LogonId = 0x00; queryRowsRequest.InputHandleIndex = 0x00; queryRowsRequest.QueryRowsFlags = 0x00; queryRowsRequest.ForwardRead = 0x01; queryRowsRequest.RowCount = 1; this.Adapter.DoRopCall(queryRowsRequest, tableHandle, ref ropResponse, ref this.responseHandles); queryRowsResponse = (RopQueryRowsResponse)ropResponse; ulong messageID = BitConverter.ToUInt64(queryRowsResponse.RowData.PropertyRows[0].PropertyValues[0].Value, 0); // Add the debug information this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCFOLD_R661"); // Verify MS-OXCFOLD requirement: MS-OXCFOLD_R661 this.Site.CaptureRequirementIfAreEqual<ulong>( mesageFAIId, messageID, 661, @"[In Processing a RopGetContentsTable ROP Request] The Table object that is returned provides information about messages that are directly under the Folder object on which this ROP [RopGetContentsTable ROP] is executed."); #endregion }
public void MSOXCFOLD_S03_TC10_RopGetContentsTableFailure() { this.CheckWhetherSupportTransport(); this.Adapter.DoConnect(ConnectionType.PrivateMailboxServer); this.GenericFolderInitialization(); #region Step 1. The client creates a FAI message in the root folder. uint messageFAIHandle = 0; ulong mesageFAIId = 0; this.CreateSaveMessage(this.RootFolderHandle, this.RootFolderId, 0x01, ref mesageFAIId, ref messageFAIHandle); #endregion #region Step 2. The client creates a non-FAI message in the root folder. uint messageNonFAIHandle = 0; ulong mesageNonFAIId = 0; this.CreateSaveMessage(this.RootFolderHandle, this.RootFolderId, ref mesageNonFAIId, ref messageNonFAIHandle); #endregion #region Step 3. The client calls RopGetContentsTable with a logon object handle rather than a folder handle. RopGetContentsTableRequest getContentsTableRequest = new RopGetContentsTableRequest { RopId = (byte)RopId.RopGetContentsTable, LogonId = Constants.CommonLogonId, InputHandleIndex = Constants.CommonInputHandleIndex, OutputHandleIndex = Constants.CommonOutputHandleIndex, TableFlags = (byte)FolderTableFlags.None }; // Use logon object handle in which case is purposed get test error code ecNotSupported [0x80040102]. RopGetContentsTableResponse getContentsTableResponse = this.Adapter.GetContentsTable(getContentsTableRequest, this.LogonHandle, ref this.responseHandles); Site.Assert.AreEqual<uint>(0x80040102, getContentsTableResponse.ReturnValue, "RopGetContentsTable ROP operation failed with ecNotSupported [0x80040102]."); #region Verify the requirements: MS-OXCFOLD_R671, MS-OXCFOLD_R672. // Add the debug information Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCFOLD_R671"); // Verify MS-OXCFOLD requirement: MS-OXCFOLD_R671 Site.CaptureRequirementIfAreEqual<uint>( 0x80040102, getContentsTableResponse.ReturnValue, 671, @"[In Processing a RopGetContentsTable ROP Request] The value of error code ecNotSupported is 0x80040102."); // Add the debug information Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCFOLD_R672"); // Verify MS-OXCFOLD requirement: MS-OXCFOLD_R672 Site.CaptureRequirementIfAreEqual<uint>( 0x80040102, getContentsTableResponse.ReturnValue, 672, @"[In Processing a RopGetContentsTable ROP Request] When the error code is ecNotSupported, it indicates that the object that this ROP [RopGetContentsTable ROP] was called on is not a Folder object."); #endregion #endregion #region Step 4. The client calls RopGetContentsTable operation with invalid 'TableFlags'. // Set an invalid TableFlags in the RopGetContentsTable ROP operation request. getContentsTableRequest.TableFlags = 0x04; getContentsTableResponse = this.Adapter.GetContentsTable(getContentsTableRequest, this.RootFolderHandle, ref this.responseHandles); #region Verify the requirements: MS-OXCFOLD_R1178, MS-OXCFOLD_R330002, MS-OXCFOLD_R1179, and MS-OXCFOLD_R330001. if (Common.IsRequirementEnabled(330002, this.Site)) { // Add the debug information Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCFOLD_R330002"); // Verify MS-OXCFOLD requirement: MS-OXCFOLD_R330002 Site.CaptureRequirementIfAreEqual<uint>( 0x80070057, getContentsTableResponse.ReturnValue, 330002, @"[In Appendix A: Product Behavior] If the client sets an invalid bit in the TableFlags field, implementation fails the ROP [RopGetContentsTable]. (Microsoft Exchange Server 2010 and above follow this behavior.)"); // Add the debug information Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCFOLD_R1178"); // Verify MS-OXCFOLD requirement: MS-OXCFOLD_R1178 Site.CaptureRequirementIfAreEqual<uint>( 0x80070057, getContentsTableResponse.ReturnValue, 1178, @"[In Processing a RopGetContentsTable ROP Request] The value of error code ecInvalidParam is 0x80070057."); // Add the debug information Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCFOLD_R1179"); // Verify MS-OXCFOLD requirement: MS-OXCFOLD_R1179 Site.CaptureRequirementIfAreEqual<uint>( 0x80070057, getContentsTableResponse.ReturnValue, 1179, @"[In Processing a RopGetContentsTable ROP Request] When the error code is ecInvalidParam, it indicates that an invalid value was specified in a field."); } if (Common.IsRequirementEnabled(330001, this.Site)) { // Add the debug information Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCFOLD_R330001"); // Verify MS-OXCFOLD requirement: MS-OXCFOLD_R330001 Site.CaptureRequirementIfAreEqual<uint>( Constants.SuccessCode, getContentsTableResponse.ReturnValue, 330001, @"[In Appendix A: Product Behavior] If the client sets an invalid bit in the TableFlags field, implementation does not fail the ROP [RopGetContentsTable]. <22> Section 3.2.5.14: Exchange 2007 ignores invalid bits instead of failing the ROP."); } #endregion #endregion }
/// <summary> /// Retrieve the content table for a folder. /// </summary> /// <param name="serverId">A 32-bit signed integer represent the Identity of server.</param> /// <param name="folderHandleIndex">The folder handle index</param> /// <param name="deleteFlags">The delete flag indicates whether checking delete.</param> /// <param name="rowCount">The row count.</param> /// <returns>Indicate the result of this ROP operation.</returns> public RopResult GetContentsTable(int serverId, int folderHandleIndex, DeleteFlags deleteFlags, out int rowCount) { RopResult result = RopResult.InvalidParameter; rowCount = -1; uint objHandle = this.handleContainer[folderHandleIndex]; RopGetContentsTableRequest getContentsTableRequest = new RopGetContentsTableRequest(); RopGetContentsTableResponse getContentsTableResponse = new RopGetContentsTableResponse(); getContentsTableRequest.RopId = 0x05; getContentsTableRequest.LogonId = 0x00; getContentsTableRequest.InputHandleIndex = 0x00; getContentsTableRequest.OutputHandleIndex = 0x01; // If this bit is set, the contents table lists only the soft-deleted messages. getContentsTableRequest.TableFlags = 0x20; getContentsTableResponse = (RopGetContentsTableResponse)this.Process(serverId, getContentsTableRequest, objHandle); result = (RopResult)getContentsTableResponse.ReturnValue; int expectedRowCount = (int)getContentsTableResponse.RowCount; // Add this condition to match the model logical for return result, it's better to compare. if (deleteFlags == DeleteFlags.SoftDeleteCheck && this.currentSoftDeleteRowCount + 1 == expectedRowCount) { rowCount = 1; } else if (deleteFlags == DeleteFlags.HardDeleteCheck && this.currentSoftDeleteRowCount == expectedRowCount) { rowCount = 0; } else if (deleteFlags == DeleteFlags.Initial) { rowCount = 0; } else if (deleteFlags == DeleteFlags.SoftDeleteCheck && this.isImportMessageMoveROP && this.currentSoftDeleteRowCount + 1 == expectedRowCount) { rowCount = 1; } this.currentSoftDeleteRowCount = expectedRowCount; return result; }
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 MSOXCFOLD_S04_TC10_RopHardDeleteMessagesInPublicFolder() { this.CheckWhetherSupportTransport(); this.Logon(); this.PublicFolderInitialization(); #region Step 1. The client creates a message in the root public folder. ulong messageId = 0; uint messageHandle = 0; this.CreateSaveMessage(this.publicRootFolderHandle, this.publicRootFolderId, ref messageId, ref messageHandle); #endregion #region Step 2. The client calls RopGetContentsTable to retrieve the contents table of the root public folder. RopGetContentsTableRequest getContentsTableRequestFirst = new RopGetContentsTableRequest { RopId = (byte)RopId.RopGetContentsTable, LogonId = Constants.CommonLogonId, InputHandleIndex = Constants.CommonInputHandleIndex, OutputHandleIndex = Constants.CommonOutputHandleIndex, TableFlags = 0x00 }; // Get the Contents table of the opened folder. RopGetContentsTableResponse getContentsTableResponseFirst = this.Adapter.GetContentsTable(getContentsTableRequestFirst, this.publicRootFolderHandle, ref this.responseHandles); uint rowCountFirst = getContentsTableResponseFirst.RowCount; #endregion #region Step 3. The client calls RopHardDeleteMessage to delete this message in the root public folder. object ropResponse = null; ulong[] messageIds = new ulong[] { messageId }; RopHardDeleteMessagesRequest hardDeleteMessagesRequest = new RopHardDeleteMessagesRequest(); RopHardDeleteMessagesResponse hardDeleteMessagesResponse = new RopHardDeleteMessagesResponse(); hardDeleteMessagesRequest.RopId = (byte)RopId.RopHardDeleteMessages; hardDeleteMessagesRequest.LogonId = Constants.CommonLogonId; hardDeleteMessagesRequest.InputHandleIndex = Constants.CommonInputHandleIndex; hardDeleteMessagesRequest.WantAsynchronous = 0x00; // The server does not generate a non-read receipt for the deleted messages. hardDeleteMessagesRequest.NotifyNonRead = 0x00; hardDeleteMessagesRequest.MessageIdCount = (ushort)messageIds.Length; hardDeleteMessagesRequest.MessageIds = messageIds; this.Adapter.DoRopCall(hardDeleteMessagesRequest, this.publicRootFolderHandle, ref ropResponse, ref this.responseHandles); hardDeleteMessagesResponse = (RopHardDeleteMessagesResponse)ropResponse; // Add the debug information Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCFOLD_R99401"); // Verify MS-OXCFOLD requirement: MS-OXCFOLD_R99401 Site.CaptureRequirementIfAreEqual<uint>( Constants.SuccessCode, hardDeleteMessagesResponse.ReturnValue, 99401, @"[In RopHardDeleteMessages ROP] This ROP [RopHardDeleteMessages] applies to both public folders [and private mailboxes]."); #endregion #region Step 4. The client calls RopGetContentsTable to retrieve the contents table of the root public folder. RopGetContentsTableRequest getContentsTableRequestSecond = new RopGetContentsTableRequest { RopId = (byte)RopId.RopGetContentsTable, LogonId = Constants.CommonLogonId, InputHandleIndex = Constants.CommonInputHandleIndex, OutputHandleIndex = Constants.CommonOutputHandleIndex, TableFlags = (byte)FolderTableFlags.Depth }; // Get the Contents table of the opened folder. RopGetContentsTableResponse getContentsTableResponseSecond = this.Adapter.GetContentsTable(getContentsTableRequestSecond, this.publicRootFolderHandle, ref this.responseHandles); uint rowCountSecond = getContentsTableResponseSecond.RowCount; Assert.AreEqual<uint>(rowCountFirst - 1, rowCountSecond, "If ROP succeeds, the second RowCount value returned from server should be one less than the first one. "); #endregion }
public void MSOXCFOLD_S04_TC12_RopGetContentsTableFromPublicFolder() { this.CheckWhetherSupportTransport(); this.Logon(); this.PublicFolderInitialization(); #region Step 1. The client calls RopCreateFolder to create [MSOXCFOLDSubfolder1] under the root public folder. uint folderHandle1 = 0; ulong folderId1 = 0; this.CreateFolder(this.publicRootFolderHandle, Constants.Subfolder1, ref folderId1, ref folderHandle1); #endregion #region Step 2. The client creates a message in the public root folder. ulong messageId = 0; uint messageHandle = 0; this.CreateSaveMessage(this.publicRootFolderHandle, this.publicRootFolderId, ref messageId, ref messageHandle); #endregion #region Step 3. The client calls RopGetContentsTable retrieve the contents table for the public root folder. RopGetContentsTableRequest getContentsTableRequest = new RopGetContentsTableRequest { RopId = (byte)RopId.RopGetContentsTable, LogonId = Constants.CommonLogonId, InputHandleIndex = Constants.CommonInputHandleIndex, OutputHandleIndex = Constants.CommonOutputHandleIndex, TableFlags = 0xC8 }; RopGetContentsTableResponse getContentsTableResponse = this.Adapter.GetContentsTable(getContentsTableRequest, this.publicRootFolderHandle, ref this.responseHandles); // Add the debug information. Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCFOLD_R100501"); // Verify MS-OXCFOLD requirement: MS-OXCFOLD_R100501. Site.CaptureRequirementIfAreEqual<uint>( Constants.SuccessCode, getContentsTableResponse.ReturnValue, 100501, @"[In RopGetContentsTable ROP] This ROP [RopGetContentsTable] applies to both public folders [and private mailboxes]."); #endregion }
public void MSOXCFOLD_S04_TC08_RopHardDeleteMessagesAndSubfoldersInPublicFolder() { if (!Common.IsRequirementEnabled(98301002, this.Site)) { this.NeedCleanup = false; Site.Assert.Inconclusive("The server does not support the RopHardDeleteMessagesAndSubfolders ROP for public folders."); } this.CheckWhetherSupportTransport(); this.Logon(); this.PublicFolderInitialization(); #region Step 1. The client calls RopCreateFolder to create [MSOXCFOLDSubfolder1] under the root public folder. RopCreateFolderRequest createFolderRequest = new RopCreateFolderRequest(); RopCreateFolderResponse createFolderResponse = new RopCreateFolderResponse(); createFolderRequest.RopId = (byte)RopId.RopCreateFolder; createFolderRequest.LogonId = Constants.CommonLogonId; createFolderRequest.InputHandleIndex = Constants.CommonInputHandleIndex; createFolderRequest.OutputHandleIndex = Constants.CommonOutputHandleIndex; createFolderRequest.FolderType = (byte)FolderType.Genericfolder; createFolderRequest.UseUnicodeStrings = 0x0; createFolderRequest.OpenExisting = 0x01; createFolderRequest.Reserved = 0x0; createFolderRequest.DisplayName = Encoding.ASCII.GetBytes(Constants.Subfolder1); createFolderRequest.Comment = Encoding.ASCII.GetBytes(Constants.Subfolder1); createFolderResponse = this.Adapter.CreateFolder(createFolderRequest, this.publicRootFolderHandle, ref this.responseHandles); Site.Assert.AreEqual<uint>(0, createFolderResponse.ReturnValue, "RopCreateFolder ROP operation performs successfully."); uint subfolderHandle1 = this.responseHandles[0][createFolderResponse.OutputHandleIndex]; #endregion #region Step 2. The client calls RopCreateFolder to create [MSOXCFOLDSubfolder2] under [MSOXCFOLDSubfolder1]. createFolderRequest.DisplayName = Encoding.ASCII.GetBytes(Constants.Subfolder2); createFolderRequest.Comment = Encoding.ASCII.GetBytes(Constants.Subfolder2); createFolderResponse = this.Adapter.CreateFolder(createFolderRequest, subfolderHandle1, ref this.responseHandles); Site.Assert.AreEqual<uint>(0, createFolderResponse.ReturnValue, "RopCreateFolder ROP operation performs successfully."); #endregion #region Step 3. The client creates a message in [MSOXCFOLDSubfolder1]. uint messageHandle = 0; ulong messageId = 0; this.CreateSaveMessage(this.publicRootFolderHandle, this.publicRootFolderId, ref messageId, ref messageHandle); #endregion #region Step 4. The client calls RopHardDeleteMessagesAndSubfolders applying to [MSOXCFOLDSubfolder1]. object ropResponse = new object(); RopHardDeleteMessagesAndSubfoldersRequest hardDeleteMessagesAndSubfoldersRequest = new RopHardDeleteMessagesAndSubfoldersRequest(); RopHardDeleteMessagesAndSubfoldersResponse hardDeleteMessagesAndSubfoldersResponse; hardDeleteMessagesAndSubfoldersRequest.RopId = (byte)RopId.RopHardDeleteMessagesAndSubfolders; hardDeleteMessagesAndSubfoldersRequest.LogonId = Constants.CommonLogonId; hardDeleteMessagesAndSubfoldersRequest.InputHandleIndex = Constants.CommonInputHandleIndex; hardDeleteMessagesAndSubfoldersRequest.WantAsynchronous = 0x00; hardDeleteMessagesAndSubfoldersRequest.WantDeleteAssociated = 0xFF; this.Adapter.DoRopCall(hardDeleteMessagesAndSubfoldersRequest, subfolderHandle1, ref ropResponse, ref this.responseHandles); hardDeleteMessagesAndSubfoldersResponse = (RopHardDeleteMessagesAndSubfoldersResponse)ropResponse; Site.Assert.AreEqual<uint>(0, hardDeleteMessagesAndSubfoldersResponse.ReturnValue, "RopHardDeleteMessagesAndSubfolders ROP operation performs successfully."); Site.Assert.AreEqual<uint>(0, hardDeleteMessagesAndSubfoldersResponse.PartialCompletion, "If delete all subsets of targets succeeds, PartialCompletion of its response will be 0 (success)"); #endregion #region Step 5. The client calls GetContentsTable to retrieve the contents table of [MSOXCFOLDSubfolder1]. RopGetContentsTableRequest getContentsTableRequest = new RopGetContentsTableRequest { RopId = (byte)RopId.RopGetContentsTable, LogonId = Constants.CommonLogonId, InputHandleIndex = Constants.CommonInputHandleIndex, OutputHandleIndex = Constants.CommonOutputHandleIndex, TableFlags = (byte)FolderTableFlags.None }; RopGetContentsTableResponse getContentsTableResponse = this.Adapter.GetContentsTable(getContentsTableRequest, subfolderHandle1, ref this.responseHandles); Site.Assert.AreEqual<uint>(Constants.SuccessCode, getContentsTableResponse.ReturnValue, "RopGetContentsTable ROP operation performs successfully!"); #endregion #region Step 6. The client calls GetHierarchyTable to retrieve the hierarchy table of [MSOXCFOLDSubfolder1]. RopGetHierarchyTableRequest getHierarchyTableRequest = new RopGetHierarchyTableRequest { RopId = (byte)RopId.RopGetHierarchyTable, LogonId = Constants.CommonLogonId, InputHandleIndex = Constants.CommonInputHandleIndex, OutputHandleIndex = Constants.CommonOutputHandleIndex, TableFlags = (byte)FolderTableFlags.None }; RopGetHierarchyTableResponse getHierarchyTableResponse = this.Adapter.GetHierarchyTable(getHierarchyTableRequest, subfolderHandle1, ref this.responseHandles); Site.Assert.AreEqual<uint>(Constants.SuccessCode, getHierarchyTableResponse.ReturnValue, "RopGetHierarchyTable ROP operation performs successfully!"); // Add the debug information. Site.Log.Add( LogEntryKind.Debug, "Verify MS-OXCFOLD_R98301002: The message count of the target folder after RopEmptyFolder is {0}, the subfolder count of the target folder after RopEmptyFolder is {1}", getContentsTableResponse.RowCount, getHierarchyTableResponse.RowCount); bool isVerifyR98301002 = getHierarchyTableResponse.RowCount == 0 && getContentsTableResponse.RowCount == 0; // Verify MS-OXCFOLD requirement: MS-OXCFOLD_R98301002. Site.CaptureRequirementIfIsTrue( isVerifyR98301002, 98301002, @"[In Appendix A: Product Behavior] Implementation does support the RopHardDeleteMessagesAndSubfolders ROP ([MS-OXCROPS] section 2.2.4.10) for public folders. (Microsoft Exchange Server 2007 and Microsoft Exchange Server 2010 follow this behavior.)"); #endregion }
public void MSOXCFOLD_S04_TC09_RopDeleteMessagesInPublicFolder() { this.CheckWhetherSupportTransport(); this.Logon(); this.PublicFolderInitialization(); #region Step 1. The client creates a message in the root public folder. ulong messageId = 0; uint messageHandle = 0; this.CreateSaveMessage(this.publicRootFolderHandle, this.publicRootFolderId, ref messageId, ref messageHandle); #endregion #region Step 2. The client calls RopGetContentsTable to retrieve the contents table of the root public folder. RopGetContentsTableRequest getContentsTableRequestFirst = new RopGetContentsTableRequest { RopId = (byte)RopId.RopGetContentsTable, LogonId = Constants.CommonLogonId, InputHandleIndex = Constants.CommonInputHandleIndex, OutputHandleIndex = Constants.CommonOutputHandleIndex, TableFlags = 0x00 }; // Get the Contents table of the opened folder. RopGetContentsTableResponse getContentsTableResponseFirst = this.Adapter.GetContentsTable(getContentsTableRequestFirst, this.publicRootFolderHandle, ref this.responseHandles); uint rowCountFirst = getContentsTableResponseFirst.RowCount; #endregion #region Step 3. The client calls RopDeleteMessages to delete this message in the root public folder. RopDeleteMessagesRequest deleteMessagesRequest = new RopDeleteMessagesRequest(); // Organize the DeleteMessage request. ulong[] messageIdsDeleted = new ulong[1]; messageIdsDeleted[0] = messageId; deleteMessagesRequest.RopId = (byte)RopId.RopDeleteMessages; deleteMessagesRequest.LogonId = Constants.CommonLogonId; deleteMessagesRequest.InputHandleIndex = Constants.CommonInputHandleIndex; deleteMessagesRequest.MessageIdCount = (ushort)messageIdsDeleted.Length; deleteMessagesRequest.MessageIds = messageIdsDeleted; RopDeleteMessagesResponse deleteMessagesResponse = this.Adapter.DeleteMessages(deleteMessagesRequest, this.publicRootFolderHandle, ref this.responseHandles); // Add the debug information Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCFOLD_R98801"); // Verify MS-OXCFOLD requirement: MS-OXCFOLD_R98801 Site.CaptureRequirementIfAreEqual<uint>( Constants.SuccessCode, deleteMessagesResponse.ReturnValue, 98801, @"[In RopDeleteMessages ROP] This ROP [RopDeleteMessages] applies to both public folders [and private mailboxes]."); #endregion #region Step 4. The client calls RopGetContentsTable to retrieve the contents table of the root public folder. RopGetContentsTableRequest getContentsTableRequestSecond = new RopGetContentsTableRequest { RopId = (byte)RopId.RopGetContentsTable, LogonId = Constants.CommonLogonId, InputHandleIndex = Constants.CommonInputHandleIndex, OutputHandleIndex = Constants.CommonOutputHandleIndex, TableFlags = 0x00 }; // Get the Contents table of the opened folder. RopGetContentsTableResponse getContentsTableResponseSecond = this.Adapter.GetContentsTable(getContentsTableRequestSecond, this.publicRootFolderHandle, ref this.responseHandles); uint rowCountSecond = getContentsTableResponseSecond.RowCount; Assert.AreEqual<uint>(rowCountFirst - 1, rowCountSecond, "If ROP succeeds, the second RowCount value returned from server should be one less than the first one. "); #endregion }
public void MSOXCFOLD_S02_TC04_RopDeleteMessagesSuccess() { this.CheckWhetherSupportTransport(); this.Adapter.DoConnect(ConnectionType.PrivateMailboxServer); this.GenericFolderInitialization(); #region Step 1. Create tree message in root folder. uint messageHandle = 0; ulong messageId = 0; this.CreateSaveMessage(this.RootFolderHandle, this.RootFolderId, ref messageId, ref messageHandle); uint messageHandle2 = 0; ulong messageId2 = 0; this.CreateSaveMessage(this.RootFolderHandle, this.RootFolderId, ref messageId2, ref messageHandle2); uint messageHandle3 = 0; ulong messageId3 = 0; this.CreateSaveMessage(this.RootFolderHandle, this.RootFolderId, ref messageId3, ref messageHandle3); #endregion #region Step 2. Delete the message created in step 1 in root folder. this.OpenMessage(messageId, this.RootFolderHandle, MessageOpenModeFlags.ReadWrite); object ropResponse = null; ulong[] messageIds = new ulong[] { messageId }; RopDeleteMessagesRequest deleteMessagesRequest = new RopDeleteMessagesRequest(); RopDeleteMessagesResponse deleteMessagesResponse; deleteMessagesRequest.RopId = (byte)RopId.RopDeleteMessages; deleteMessagesRequest.LogonId = Constants.CommonLogonId; deleteMessagesRequest.InputHandleIndex = Constants.CommonInputHandleIndex; deleteMessagesRequest.WantAsynchronous = 0x00; // The server does not generate a non-read receipt for the deleted messages. deleteMessagesRequest.NotifyNonRead = 0x00; deleteMessagesRequest.MessageIdCount = (ushort)messageIds.Length; deleteMessagesRequest.MessageIds = messageIds; this.Adapter.DoRopCall(deleteMessagesRequest, this.RootFolderHandle, ref ropResponse, ref this.responseHandles); deleteMessagesResponse = (RopDeleteMessagesResponse)ropResponse; Site.Assert.AreEqual<uint>( 0, deleteMessagesResponse.ReturnValue, "If ROP succeeds, the ReturnValue of its response is 0(success)"); // Add the debug information Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCFOLD_R1143"); // Verify MS-OXCFOLD requirement: MS-OXCFOLD_R1143 Site.CaptureRequirementIfAreEqual<Type>( typeof(RopDeleteMessagesResponse), ropResponse.GetType(), 1143, @"[In Processing a RopDeleteMessages ROP Request] The server responds with a RopDeleteMessages ROP response buffer."); // Add the debug information Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCFOLD_R98802"); // Verify MS-OXCFOLD requirement: MS-OXCFOLD_R98802. // The RopDeleteMessages ROP operation performs successfully on a private mailbox, MS-OXCFOLD_R98802 can be captured directly. Site.CaptureRequirement( 98802, @"[In RopDeleteMessages ROP] This ROP [RopDeleteMessages] applies to [both public folders and] private mailboxes."); // Add the debug information. Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCFOLD_R271"); // Verify MS-OXCFOLD requirement: MS-OXCFOLD_R271. // The WantAsynchronous was set to zero and the server responds a RopDeleteMessages ROP response indicates the ROP is processed synchronously, MS-OXCFOLD_R271 can be verified directly. Site.CaptureRequirement( 271, @"[In RopDeleteMessages ROP Request Buffer] WantAsynchronous (1 byte): [A Boolean value that is] zero (FALSE) if the ROP is to be processed synchronously."); #region Verify MS-OXCFOLD_R282 and MS-OXCFOLD_R436. // Add the debug information. Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCFOLD_R282"); // Verify MS-OXCFOLD requirement: MS-OXCFOLD_R282. Site.CaptureRequirementIfAreEqual<uint>( 0, deleteMessagesResponse.PartialCompletion, 282, "[In RopDeleteMessages ROP Response Buffer] PartialCompletion (1 byte): Otherwise [if the ROP successes for a subset of targets], the value [of PartialCompletion field] is zero (FALSE)."); // Add the debug information. Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCFOLD_R436"); // Verify MS-OXCFOLD requirement: MS-OXCFOLD_R436. // The RopDeleteMessage performs successfully, and MS-OXCFOLD_R282 is verified, MS-OXCFOLD_R436 can be verified directly. Site.CaptureRequirement( 436, "[In Deleting the Contents of a Folder] To remove particular messages from a folder, the client sends [either] a RopDeleteMessages ROP request ([MS-OXCROPS] section 2.2.4.11) [or a RopHardDeleteMessages ROP request ([MS-OXCROPS] section 2.2.4.12)]."); #endregion messageIds = new ulong[] { messageId2, messageId3 }; deleteMessagesRequest.RopId = (byte)RopId.RopDeleteMessages; deleteMessagesRequest.LogonId = Constants.CommonLogonId; deleteMessagesRequest.InputHandleIndex = Constants.CommonInputHandleIndex; deleteMessagesRequest.WantAsynchronous = 0x00; // The server does not generate a non-read receipt for the deleted messages. deleteMessagesRequest.NotifyNonRead = 0x00; deleteMessagesRequest.MessageIdCount = (ushort)messageIds.Length; deleteMessagesRequest.MessageIds = messageIds; this.Adapter.DoRopCall(deleteMessagesRequest, this.RootFolderHandle, ref ropResponse, ref this.responseHandles); #region Verify MS-OXCFOLD_R262 and MS-OXCFOLD_R1017. bool allDeleted = this.IsMessageDeleted(messageId2, this.RootFolderId) && this.IsMessageDeleted(messageId3, this.RootFolderId); // Add the debug information. Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCFOLD_R262"); // Verify MS-OXCFOLD requirement: MS-OXCFOLD_R262. Site.CaptureRequirementIfIsTrue( allDeleted, 262, "[In RopDeleteMessages ROP] The RopDeleteMessages ROP ([MS-OXCROPS] section 2.2.4.11) is used to soft delete one or more messages from a folder."); RopGetContentsTableRequest getContentsTableRequest = new RopGetContentsTableRequest { RopId = (byte)RopId.RopGetContentsTable, LogonId = Constants.CommonLogonId, InputHandleIndex = Constants.CommonInputHandleIndex, OutputHandleIndex = Constants.CommonOutputHandleIndex, TableFlags = (byte)FolderTableFlags.SoftDeletes }; RopGetContentsTableResponse getContentsTableResponse = this.Adapter.GetContentsTable(getContentsTableRequest, this.RootFolderHandle, ref this.responseHandles); Site.Assert.AreEqual<uint>(Constants.SuccessCode, getContentsTableResponse.ReturnValue, "RopGetContentsTable ROP operation performs successfully!"); if (Common.IsRequirementEnabled(1017, this.Site)) { // Add the debug information Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCFOLD_R1017"); // Verify MS-OXCFOLD requirement: MS-OXCFOLD_R1017 // Method GetContentsTable succeeds and it's row count is 3, this requirement verified. Site.CaptureRequirementIfAreEqual<uint>( 3, getContentsTableResponse.RowCount, 1017, @"[In RopGetContentsTable ROP Request Buffer] If this bit [SoftDeletes] is set, the contents table lists only the messages that are soft deleted."); } #endregion #endregion }
public void MSOXCFOLD_S02_TC11_RopMoveCopyMessagesUseSearchFolderSuccess() { this.Adapter.DoConnect(ConnectionType.PrivateMailboxServer); this.GenericFolderInitialization(); #region Step 1. Call RopCreateFolder to create [MSOXCFOLDSubfolder1] under the root folder. ulong subfolderId1 = 0; uint subfolderHandle1 = 0; this.CreateFolder(this.RootFolderHandle, Constants.Subfolder1, ref subfolderId1, ref subfolderHandle1); #endregion #region Step 2. Create a message in the [MSOXCFOLDSubfolder1] folder created in step 1. uint messageHandle = 0; ulong messageId = 0; this.CreateSaveMessage(subfolderHandle1, subfolderId1, ref messageId, ref messageHandle); #endregion #region Step 3. Call RopCreateFolder to create [MSOXCFOLDSubfolder2] under the root folder. ulong subfolderId2 = 0; uint subfolderHandle2 = 0; this.CreateFolder(this.RootFolderHandle, Constants.Subfolder2, ref subfolderId2, ref subfolderHandle2); #endregion #region Step 4. Create a message in the [MSOXCFOLDSubfolder2] folder created in step 3. uint messageHandleInSubFolder2 = 0; ulong messageIdInSubFolder2 = 0; this.CreateSaveMessage(subfolderHandle2, subfolderId2, ref messageIdInSubFolder2, ref messageHandleInSubFolder2); #endregion #region Step 4. Call RopCreateFolder to create a search folder [MSOXCFOLDSearchFolder] under the root folder. RopCreateFolderRequest createFolderRequest = new RopCreateFolderRequest { RopId = (byte)RopId.RopCreateFolder, LogonId = Constants.CommonLogonId, InputHandleIndex = Constants.CommonInputHandleIndex, OutputHandleIndex = Constants.CommonOutputHandleIndex, FolderType = (byte)FolderType.Searchfolder, UseUnicodeStrings = 0x0, OpenExisting = 0x00, Reserved = 0x0, DisplayName = Encoding.ASCII.GetBytes(Constants.SearchFolder), Comment = Encoding.ASCII.GetBytes(Constants.SearchFolder) }; RopCreateFolderResponse createFolderResponse = this.Adapter.CreateFolder(createFolderRequest, this.RootFolderHandle, ref this.responseHandles); Site.Assert.AreEqual<uint>(Constants.SuccessCode, createFolderResponse.ReturnValue, "RopCreateFolder ROP operation performs successfully!"); uint searchFolderHandle = this.responseHandles[0][createFolderResponse.OutputHandleIndex]; #endregion #region Step 5. The client calls RopSetSearchCriteria to establish search criteria for [MSOXCFOLDSubFolder1]. RopSetSearchCriteriaRequest setSearchCriteriaRequest = new RopSetSearchCriteriaRequest { RopId = (byte)RopId.RopSetSearchCriteria, LogonId = Constants.CommonLogonId, InputHandleIndex = Constants.CommonInputHandleIndex }; PropertyTag propertyTag = new PropertyTag { PropertyId = (ushort)MessagePropertyId.PidTagMessageClass, PropertyType = (ushort)PropertyType.PtypString }; ExistRestriction existRestriction = new ExistRestriction { PropTag = propertyTag }; setSearchCriteriaRequest.RestrictionDataSize = (ushort)existRestriction.Size(); setSearchCriteriaRequest.RestrictionData = existRestriction.Serialize(); setSearchCriteriaRequest.FolderIds = new ulong[] { subfolderId1 }; setSearchCriteriaRequest.FolderIdCount = (ushort)setSearchCriteriaRequest.FolderIds.Length; setSearchCriteriaRequest.SearchFlags = (uint)SetSearchFlags.ContentIndexedSearch | (uint)SetSearchFlags.StaticSearch | (uint)SetSearchFlags.RestartSearch; RopSetSearchCriteriaResponse setSearchCriteriaResponse = this.Adapter.SetSearchCriteria(setSearchCriteriaRequest, searchFolderHandle, ref this.responseHandles); Site.Assert.AreEqual<uint>(Constants.SuccessCode, setSearchCriteriaResponse.ReturnValue, "RopSearchCriteria ROP operation performs successfully!"); #endregion #region Step 6. The client calls RopGetSearchCriteria to obtain the search criteria and the status of the search folder [MSOXCFOLDSubFolder1]. RopGetSearchCriteriaRequest getSearchCriteriaRequest = new RopGetSearchCriteriaRequest { RopId = (byte)RopId.RopGetSearchCriteria, LogonId = Constants.CommonLogonId, InputHandleIndex = Constants.CommonInputHandleIndex, UseUnicode = 0x00, IncludeRestriction = 0x01, IncludeFolders = 0x01 }; RopGetSearchCriteriaResponse getSearchCriteriaResponse = this.Adapter.GetSearchCriteria(getSearchCriteriaRequest, searchFolderHandle, ref this.responseHandles); Site.Assert.AreEqual<uint>(Constants.SuccessCode, getSearchCriteriaResponse.ReturnValue, "RopGetSearchCriteria ROP operation performs successfully!"); #endregion #region Step 7. The client calls RopGetContentsTable to get handle of the contents table in the search folder [MSOXCFOLDSearchFolder]. RopGetContentsTableRequest getContentsTableRequest = new RopGetContentsTableRequest(); RopGetContentsTableResponse getContentsTableResponse; getContentsTableRequest.RopId = (byte)RopId.RopGetContentsTable; getContentsTableRequest.LogonId = Constants.CommonLogonId; getContentsTableRequest.InputHandleIndex = Constants.CommonInputHandleIndex; getContentsTableRequest.OutputHandleIndex = Constants.CommonOutputHandleIndex; getContentsTableRequest.TableFlags = (byte)FolderTableFlags.None; int count = 0; uint tableHandle; do { getContentsTableResponse = this.Adapter.GetContentsTable(getContentsTableRequest, searchFolderHandle, ref this.responseHandles); Site.Assert.AreEqual<uint>(Constants.SuccessCode, getContentsTableResponse.ReturnValue, "RopGetContentsTable ROP operation performs successfully!"); tableHandle = this.responseHandles[0][getContentsTableResponse.OutputHandleIndex]; if (getContentsTableResponse.RowCount != 1) { Thread.Sleep(this.WaitTime); } else { break; } count++; } while (count < this.RetryCount); #endregion #region Step 8. Sets the properties PidTagMid visible on the content table. RopSetColumnsRequest setColumnsRequest; PropertyTag[] propertyTags = new PropertyTag[1]; propertyTags[0].PropertyId = (ushort)MessagePropertyId.PidTagMid; propertyTags[0].PropertyType = (ushort)PropertyType.PtypInteger64; setColumnsRequest.RopId = 0x12; setColumnsRequest.LogonId = 0x00; setColumnsRequest.InputHandleIndex = 0x00; setColumnsRequest.PropertyTagCount = (ushort)propertyTags.Length; setColumnsRequest.PropertyTags = propertyTags; setColumnsRequest.SetColumnsFlags = 0x00; // Sync object ropResponse = new object(); this.Adapter.DoRopCall(setColumnsRequest, tableHandle, ref ropResponse, ref this.responseHandles); #endregion #region Step 9. Gets the message ID in the search folder [MSOXCFOLDSearchFolder]. RopQueryRowsRequest queryRowsRequest; RopQueryRowsResponse queryRowsResponse; queryRowsRequest.RopId = 0x15; queryRowsRequest.LogonId = 0x00; queryRowsRequest.InputHandleIndex = 0x00; queryRowsRequest.QueryRowsFlags = 0x00; queryRowsRequest.ForwardRead = 0x01; queryRowsRequest.RowCount = 1; this.Adapter.DoRopCall(queryRowsRequest, tableHandle, ref ropResponse, ref this.responseHandles); queryRowsResponse = (RopQueryRowsResponse)ropResponse; ulong messageID = BitConverter.ToUInt64(queryRowsResponse.RowData.PropertyRows[0].PropertyValues[0].Value, 0); #endregion #region Step 10. Call RopMoveCopyMessages to copy the message in the [MSOXCFOLDSearchFolder] to root folder synchronously. ulong[] messageIds = new ulong[1]; messageIds[0] = messageID; List<uint> handlelist = new List<uint> { searchFolderHandle, this.RootFolderHandle }; RopMoveCopyMessagesRequest moveCopyMessagesRequest = new RopMoveCopyMessagesRequest { RopId = (byte)RopId.RopMoveCopyMessages, LogonId = Constants.CommonLogonId, SourceHandleIndex = 0x00, DestHandleIndex = 0x01, MessageIdCount = (ushort)messageIds.Length, MessageIds = messageIds, WantAsynchronous = 0x00, WantCopy = 0xFF }; // WantCopy is nonzero (TRUE) indicates this is a copy operation. RopMoveCopyMessagesResponse copyMessagesFromSearchFolderResponse = this.Adapter.MoveCopyMessages(moveCopyMessagesRequest, handlelist, ref this.responseHandles); Site.Assert.AreEqual<uint>(0, copyMessagesFromSearchFolderResponse.ReturnValue, "The RopMoveCopyMessages ROP operation performs successfully."); Site.Assert.AreEqual<uint>(0, copyMessagesFromSearchFolderResponse.PartialCompletion, "The ROP successes for all subsets of targets"); handlelist.Clear(); #endregion #region Step 11. Validate the message is copied successfully in above step 9. uint rootFolderContentsCountActual = this.GetContentsTable(FolderTableFlags.None, this.RootFolderHandle); // Verify MS-OXCFOLD requirement: MS-OXCFOLD_R121702. Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCFOLD_R121702: expected contents count of the root folder is {0}, actual contents count of the root folder is {1};", 1, rootFolderContentsCountActual); // The source folder is a search folder, so if the message was copied successfully from MSOXCFOLDSearchFolder to root folder, R121702 can be verified. Site.CaptureRequirementIfAreEqual<uint>( 1, rootFolderContentsCountActual, 121702, @"[In RopMoveCopyMessages ROP Request Buffer] SourceHandleIndex (1 byte): [The source Server object for this operation [RopMoveCopyMessages ROP] is a Folder object that represents the folder from which the messages will be copied] This folder can be a search folder."); #endregion #region Step 12. Call RopMoveCopyMessages to move the message in the [MSOXCFOLDSearchFolder] to root folder synchronously. messageIds = new ulong[1]; messageIds[0] = messageID; handlelist = new List<uint> { searchFolderHandle, this.RootFolderHandle }; moveCopyMessagesRequest = new RopMoveCopyMessagesRequest { RopId = (byte)RopId.RopMoveCopyMessages, LogonId = Constants.CommonLogonId, SourceHandleIndex = 0x00, DestHandleIndex = 0x01, MessageIdCount = (ushort)messageIds.Length, MessageIds = messageIds, WantAsynchronous = 0x00, WantCopy = 0x00 }; // WantCopy is zero (FALSE) indicates this is a move operation. RopMoveCopyMessagesResponse moveMessagesFromSearchFolderResponse = this.Adapter.MoveCopyMessages(moveCopyMessagesRequest, handlelist, ref this.responseHandles); Site.Assert.AreEqual<uint>(0, moveMessagesFromSearchFolderResponse.ReturnValue, "The RopMoveCopyMessages ROP operation performs successfully."); Site.Assert.AreEqual<uint>(0, moveMessagesFromSearchFolderResponse.PartialCompletion, "The ROP successes for all subsets of targets"); handlelist.Clear(); #endregion #region Step 13. Validate the message is moved successfully in above step 12. rootFolderContentsCountActual = this.GetContentsTable(FolderTableFlags.None, this.RootFolderHandle); // Verify MS-OXCFOLD requirement: MS-OXCFOLD_R121701. Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCFOLD_R121701: expected contents count of the root folder is {0}, actual contents count of the root folder is {1};", 2, rootFolderContentsCountActual); // The source folder is a search folder, so if the message was moved successfully from MSOXCFOLDSearchFolder to root folder, R121701 can be verified. Site.CaptureRequirementIfAreEqual<uint>( 2, rootFolderContentsCountActual, 121701, @"[In RopMoveCopyMessages ROP Request Buffer] SourceHandleIndex (1 byte): [The source Server object for this operation [RopMoveCopyMessages ROP] is a Folder object that represents the folder from which the messages will be moved] This folder can be a search folder."); #endregion #region Step 14. Call RopMoveCopyMessages to copy the message in the [MSOXCFOLDSubfolder2] to the [MSOXCFOLDSearchFolder] synchronously. RopMoveCopyMessagesResponse copyMessagesToSearchFolderResponse = new RopMoveCopyMessagesResponse(); if (Common.IsRequirementEnabled(1246, this.Site)) { messageIds[0] = messageIdInSubFolder2; handlelist = new List<uint> { subfolderHandle2, searchFolderHandle }; moveCopyMessagesRequest = new RopMoveCopyMessagesRequest { RopId = (byte)RopId.RopMoveCopyMessages, LogonId = Constants.CommonLogonId, SourceHandleIndex = 0x00, DestHandleIndex = 0x01, MessageIdCount = (ushort)messageIds.Length, MessageIds = messageIds, WantAsynchronous = 0x00, WantCopy = 0xFF }; // WantCopy is nonzero (TRUE) indicates this is a copy operation. copyMessagesToSearchFolderResponse = this.Adapter.MoveCopyMessages(moveCopyMessagesRequest, handlelist, ref this.responseHandles); // Add the debug information this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCFOLD_R121802: the PartialCompletion in the MoveCopyMessages response is {0}", copyMessagesToSearchFolderResponse.PartialCompletion); // Verify MS-OXCFOLD requirement: MS-OXCFOLD_R121802 // If the ROP RopMoveCopyMessages fails to copy message, the value of PartialCompletion field is nonzero. this.Site.CaptureRequirementIfAreNotEqual<uint>( 0x00000000, copyMessagesToSearchFolderResponse.ReturnValue, 121802, @"[In RopMoveCopyMessages ROP Request Buffer] DestHandleIndex (1 byte): [The destination Server object for this operation [RopMoveCopyMessages ROP] is a Folder object that represents the folder to which the messages will be copied.] This folder cannot be a search folder."); } #endregion #region Step 15. Call RopMoveCopyMessages to move the message in the [MSOXCFOLDSubfolder2] to the [MSOXCFOLDSearchFolder] synchronously. RopMoveCopyMessagesResponse moveMessagesToSearchFolderResponse; if (Common.IsRequirementEnabled(1246, this.Site)) { messageIds[0] = messageIdInSubFolder2; handlelist = new List<uint> { subfolderHandle2, searchFolderHandle }; moveCopyMessagesRequest = new RopMoveCopyMessagesRequest { RopId = (byte)RopId.RopMoveCopyMessages, LogonId = Constants.CommonLogonId, SourceHandleIndex = 0x00, DestHandleIndex = 0x01, MessageIdCount = (ushort)messageIds.Length, MessageIds = messageIds, WantAsynchronous = 0x00, WantCopy = 0x00 }; // WantCopy is zero (FLASE) indicates this is a move operation. moveMessagesToSearchFolderResponse = this.Adapter.MoveCopyMessages(moveCopyMessagesRequest, handlelist, ref this.responseHandles); // Add the debug information this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCFOLD_R121801: the PartialCompletion in the MoveCopyMessages response is {0}", moveMessagesToSearchFolderResponse.PartialCompletion); // Verify MS-OXCFOLD requirement: MS-OXCFOLD_R121801 // If the ROP RopMoveCopyMessages fails to move message, the value of PartialCompletion field is nonzero. this.Site.CaptureRequirementIfAreNotEqual<uint>( 0x00000000, moveMessagesToSearchFolderResponse.ReturnValue, 121801, @"[In RopMoveCopyMessages ROP Request Buffer] DestHandleIndex (1 byte): [The destination Server object for this operation [RopMoveCopyMessages ROP] is a Folder object that represents the folder to which the messages will be moved.] This folder cannot be a search folder."); // Add the debug information this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCFOLD_R1216"); // Verify MS-OXCFOLD requirement: MS-OXCFOLD_R1216 bool isVerifiedR1216 = copyMessagesFromSearchFolderResponse.ReturnValue == 0x00000000 && moveMessagesFromSearchFolderResponse.ReturnValue == 0x00000000 && copyMessagesToSearchFolderResponse.ReturnValue != 0x00000000 && moveMessagesToSearchFolderResponse.ReturnValue != 0x00000000; this.Site.CaptureRequirementIfIsTrue( isVerifiedR1216, 1216, @"[In RopMoveCopyMessages ROP] The source folder can be a search folder, but the destination folder cannot."); // Add the debug information this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCFOLD_R1246: the return value is {0} when copy a message to a search folder and the return value is {1} when move a message to a search folder.", copyMessagesToSearchFolderResponse.ReturnValue, moveMessagesToSearchFolderResponse.ReturnValue); // Verify MS-OXCFOLD requirement: MS-OXCFOLD_R1246 bool isVerifiedR1246 = copyMessagesToSearchFolderResponse.ReturnValue == 0x00000460 && moveMessagesToSearchFolderResponse.ReturnValue == 0x00000460; this.Site.CaptureRequirementIfIsTrue( isVerifiedR1246, 1246, @"[In Processing a RopMoveCopyMessages ROP Request] When the error code is ecSearchFolder, it indicates the destination object is a search folder. "); // Add the debug information this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCFOLD_R1245"); // Verify MS-OXCFOLD requirement: MS-OXCFOLD_R1245 this.Site.CaptureRequirementIfAreEqual<uint>( 0x00000460, copyMessagesToSearchFolderResponse.ReturnValue, 1245, @"[In Processing a RopMoveCopyMessages ROP Request] The value of error code ecSearchFolder is 0x00000460."); } #endregion }
/// <summary> /// Retrieves the contents table for a folder. /// </summary> /// <param name="ropGetContentsTableRequest">RopGetContentsTableRequest object.</param> /// <param name="insideObjHandle">Server object handle in RopGetContentsTable.</param> /// <param name="responseSOHTable">Server objects handles in RopGetContentsTableResponse.</param> /// <returns>RopGetContentsTableResponse object.</returns> public RopGetContentsTableResponse GetContentsTable(RopGetContentsTableRequest ropGetContentsTableRequest, uint insideObjHandle, ref List<List<uint>> responseSOHTable) { object temp = new object(); RopGetContentsTableResponse ropGetContentsTableResponse; bool contentsTableLocked = true; int count = 0; int waitTime = int.Parse(Common.GetConfigurationPropertyValue("WaitTime", this.Site)); int retryCount = int.Parse(Common.GetConfigurationPropertyValue("RetryCount", this.Site)); do { this.ExcuteRopCall((ISerializable)ropGetContentsTableRequest, insideObjHandle, ref temp, ref responseSOHTable, ref this.rawData); ropGetContentsTableResponse = (RopGetContentsTableResponse)temp; // The contents table was locked by another database operation. if (ropGetContentsTableResponse.ReturnValue == 4294965994) { Site.Log.Add(LogEntryKind.Comment, " JET_errTableLocked:" + ropGetContentsTableResponse.ReturnValue); Thread.Sleep(waitTime); } else { contentsTableLocked = false; } if (count > retryCount) { break; } count++; } while (contentsTableLocked); #region Capture Code // The ReturnValue equal to 0x00000000 indicate ROP operation success if (0x00000000 == ropGetContentsTableResponse.ReturnValue) { this.VerifyRopGetContentsTable(ropGetContentsTableResponse); } #endregion return ropGetContentsTableResponse; }
public void MSOXCFOLD_S03_TC02_DynamicSearchVerification() { this.CheckWhetherSupportTransport(); this.Adapter.DoConnect(ConnectionType.PrivateMailboxServer); this.GenericFolderInitialization(); #region Step 1. The client calls RopCreateFolder to create the general folder [MSOXCFOLDSubfolder1] under the root folder. RopCreateFolderRequest createFolderRequest = new RopCreateFolderRequest(); createFolderRequest.RopId = (byte)RopId.RopCreateFolder; createFolderRequest.LogonId = Constants.CommonLogonId; createFolderRequest.InputHandleIndex = Constants.CommonInputHandleIndex; createFolderRequest.OutputHandleIndex = Constants.CommonOutputHandleIndex; createFolderRequest.FolderType = 0x01; createFolderRequest.UseUnicodeStrings = 0x0; createFolderRequest.OpenExisting = 0x00; createFolderRequest.Reserved = 0x0; createFolderRequest.DisplayName = Encoding.ASCII.GetBytes(Constants.Subfolder1); createFolderRequest.Comment = Encoding.ASCII.GetBytes(Constants.Subfolder1); RopCreateFolderResponse createFolderResponse = this.Adapter.CreateFolder(createFolderRequest, this.RootFolderHandle, ref this.responseHandles); Site.Assert.AreEqual<uint>(Constants.SuccessCode, createFolderResponse.ReturnValue, "RopCreateFolder ROP operation performs successfully!"); uint subfolderHandle1 = this.responseHandles[0][createFolderResponse.OutputHandleIndex]; ulong subfolderId1 = createFolderResponse.FolderId; #endregion #region Step 2. The client creates a non-FAI message under the general folder [MSOXCFOLDSubfolder1]. uint messageNonFAIHandle1 = 0; ulong messageNonFAIId1 = 0; this.CreateSaveMessage(subfolderHandle1, subfolderId1, ref messageNonFAIId1, ref messageNonFAIHandle1); #endregion #region Step 3. The client calls RopCreateFolder to create the search folder [MSOXCFOLDSearchFolder1] under the root folder. createFolderRequest.FolderType = 0x02; createFolderRequest.DisplayName = Encoding.ASCII.GetBytes(Constants.SearchFolder); createFolderRequest.Comment = Encoding.ASCII.GetBytes(Constants.SearchFolder); createFolderResponse = this.Adapter.CreateFolder(createFolderRequest, this.RootFolderHandle, ref this.responseHandles); Site.Assert.AreEqual<uint>(Constants.SuccessCode, createFolderResponse.ReturnValue, "RopCreateFolder ROP operation performs successfully!"); uint searchFolderHandle = this.responseHandles[0][createFolderResponse.OutputHandleIndex]; #endregion #region Step 4. The client calls RopSetSearchCriteria to establish search criteria for [MSOXCFOLDSearchFolder1]. RopSetSearchCriteriaRequest setSearchCriteriaRequest = new RopSetSearchCriteriaRequest { RopId = (byte)RopId.RopSetSearchCriteria, LogonId = Constants.CommonLogonId, InputHandleIndex = Constants.CommonInputHandleIndex }; PropertyTag propertyTag = new PropertyTag { PropertyId = (ushort)MessagePropertyId.PidTagMessageClass, PropertyType = (ushort)PropertyType.PtypString }; ExistRestriction existRestriction = new ExistRestriction { PropTag = propertyTag }; setSearchCriteriaRequest.RestrictionDataSize = (ushort)existRestriction.Size(); setSearchCriteriaRequest.RestrictionData = existRestriction.Serialize(); setSearchCriteriaRequest.FolderIds = new ulong[] { subfolderId1 }; setSearchCriteriaRequest.FolderIdCount = (ushort)setSearchCriteriaRequest.FolderIds.Length; setSearchCriteriaRequest.SearchFlags = (uint)SetSearchFlags.NonContentIndexedSearch | (uint)SetSearchFlags.RestartSearch; RopSetSearchCriteriaResponse setSearchCriteriaResponse = this.Adapter.SetSearchCriteria(setSearchCriteriaRequest, searchFolderHandle, ref this.responseHandles); Site.Assert.AreEqual<uint>(Constants.SuccessCode, setSearchCriteriaResponse.ReturnValue, "RopSearchCriteria ROP operation performs successfully!"); // Add the debug information Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCFOLD_R783"); // Verify MS-OXCFOLD requirement: MS-OXCFOLD_R783 Site.CaptureRequirementIfAreEqual<uint>( Constants.SuccessCode, setSearchCriteriaResponse.ReturnValue, 783, @"[In RopSetSearchCriteria ROP Request Buffer] SearchFlags (4 bytes): NON_CONTENT_INDEXED_SEARCH (0x00020000) means that the search does not use a content-indexed search."); #endregion #region Step 5. The client calls RopGetSearchCriteria to obtain the search criteria and the status of the search folder [MSOXCFOLDSearchFolder1]. RopGetSearchCriteriaRequest getSearchCriteriaRequest = new RopGetSearchCriteriaRequest { RopId = (byte)RopId.RopGetSearchCriteria, LogonId = Constants.CommonLogonId, InputHandleIndex = Constants.CommonInputHandleIndex, UseUnicode = 0x00, IncludeRestriction = 0x01, IncludeFolders = 0x01 }; RopGetSearchCriteriaResponse getSearchCriteriaResponse = this.Adapter.GetSearchCriteria(getSearchCriteriaRequest, searchFolderHandle, ref this.responseHandles); Site.Assert.AreEqual<uint>(Constants.SuccessCode, getSearchCriteriaResponse.ReturnValue, "RopGetSearchCriteria ROP operation performs successfully!"); // Add the debug information Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCFOLD_R785"); // Verify MS-OXCFOLD requirement: MS-OXCFOLD_R785 Site.CaptureRequirementIfAreEqual<uint>( (uint)GetSearchFlags.Running, getSearchCriteriaResponse.SearchFlags & (uint)GetSearchFlags.Running, 785, @"[In RopGetSearchCriteria ROP Response Buffer] SearchFlags (4 bytes): SEARCH_RUNNING (0x00000001) means that the search is running, which means that the initial population of the search folder still being compiled."); #endregion #region Step 6. The client calls RopGetContentsTable to retrieve the contents table for the search folder [MSOXCFOLDSearchFolder1]. RopGetContentsTableRequest getContentsTableRequest = new RopGetContentsTableRequest(); RopGetContentsTableResponse getContentsTableResponse; getContentsTableRequest.RopId = (byte)RopId.RopGetContentsTable; getContentsTableRequest.LogonId = Constants.CommonLogonId; getContentsTableRequest.InputHandleIndex = Constants.CommonInputHandleIndex; getContentsTableRequest.OutputHandleIndex = Constants.CommonOutputHandleIndex; getContentsTableRequest.TableFlags = (byte)FolderTableFlags.None; int count = 0; do { getContentsTableResponse = this.Adapter.GetContentsTable(getContentsTableRequest, searchFolderHandle, ref this.responseHandles); Site.Assert.AreEqual<uint>(Constants.SuccessCode, getContentsTableResponse.ReturnValue, "RopGetContentsTable ROP operation performs successfully!"); if (getContentsTableResponse.RowCount != 1) { Thread.Sleep(this.WaitTime); } else { break; } count++; } while (count < this.RetryCount); #region Verify the requirements: MS-OXCFOLD_R552, MS-OXCFOLD_R526. Site.Assert.AreEqual<uint>((uint)GetSearchFlags.Running, getSearchCriteriaResponse.SearchFlags & (uint)GetSearchFlags.Running, "The RopSearchCriteria ROP operation has not been complete."); // Add the debug information Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCFOLD_R526"); // If the client has received the success code from the server after sending a RopSetSearchCriteria request. // If the client has received a 'SEARCH_RUNNING' SearchFlags in the RopGetSearchCriteria response after sending a RopGetSearchCriteria response later. // If the client has got the messages which according to the search criteria and search scope that are specified in the RopSetSearchCriteria ROP request in the RopGetContentsTable response after sending a RopGetContentsTable request later. // Satisfy the above conditions, then this requirement can be verified directly. Site.CaptureRequirement( 526, @"[In Processing a RopSetSearchCriteria ROP Request] The server can return the RopSetSearchCriteria ROP response before the search folder is fully updated."); // Add the debug information Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCFOLD_R552"); // Verify MS-OXCFOLD requirement: MS-OXCFOLD_R552 // There should have 1 message macthed the search criteria, so the RowCount should be 1. Site.CaptureRequirementIfAreEqual<uint>( 1, getContentsTableResponse.RowCount, 552, @"[In Processing a RopSetSearchCriteria ROP Request] A dynamic search causes the search folder to be initially populated with all messages that match the search criteria at the point in time when the search is started or restarted."); #endregion #endregion #region Step 7. The client calls RopSetSearchCriteria without setting the SearchFlags to establish search criteria for [MSOXCFOLDSearchFolder1]. setSearchCriteriaRequest.SearchFlags = (uint)SetSearchFlags.None; setSearchCriteriaResponse = this.Adapter.SetSearchCriteria(setSearchCriteriaRequest, searchFolderHandle, ref this.responseHandles); Site.Assert.AreEqual<uint>(Constants.SuccessCode, setSearchCriteriaResponse.ReturnValue, "RopSearchCriteria ROP operation performs successfully!"); #endregion #region Step 8. The client calls RopGetSearchCriteria to obtain the search criteria and the status of the search folder [MSOXCFOLDSearchFolder1]. getSearchCriteriaResponse = this.Adapter.GetSearchCriteria(getSearchCriteriaRequest, searchFolderHandle, ref this.responseHandles); Site.Assert.AreEqual<uint>(Constants.SuccessCode, getSearchCriteriaResponse.ReturnValue, "RopGetSearchCriteria ROP operation performs successfully!"); #endregion #region Step 9. The client calls RopGetContentsTable to retrieve the contents table for the search folder [MSOXCFOLDSearchFolder1]. count = 0; do { getContentsTableResponse = this.Adapter.GetContentsTable(getContentsTableRequest, searchFolderHandle, ref this.responseHandles); Site.Assert.AreEqual<uint>(Constants.SuccessCode, getContentsTableResponse.ReturnValue, "RopGetContentsTable ROP operation performs successfully!"); if (getContentsTableResponse.RowCount != 1) { Thread.Sleep(this.WaitTime); } else { break; } count++; } while (count < this.RetryCount); #endregion #region Step 10. The client creates a non-FAI message under the general folder [MSOXCFOLDSubfolder1]. uint messageNonFAIHandle3 = 0; ulong messageNonFAIId3 = 0; this.CreateSaveMessage(subfolderHandle1, subfolderId1, ref messageNonFAIId3, ref messageNonFAIHandle3); #endregion #region Step 11. The client calls RopGetContentsTable to retrieve the contents table for the search folder [MSOXCFOLDSearchFolder1]. count = 0; do { getContentsTableResponse = this.Adapter.GetContentsTable(getContentsTableRequest, searchFolderHandle, ref this.responseHandles); Site.Assert.AreEqual<uint>(Constants.SuccessCode, getContentsTableResponse.ReturnValue, "RopGetContentsTable ROP operation performs successfully!"); if (getContentsTableResponse.RowCount != 2) { Thread.Sleep(this.WaitTime); } else { break; } count++; } while (count < this.RetryCount); #region Verify the requirements: MS-OXCFOLD_R1095, MS-OXCFOLD_R1210, MS-OXCFOLD_R1096, and MS-OXCFOLD_R1097. // Add the debug information Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCFOLD_R1096"); // Verify MS-OXCFOLD requirement: MS-OXCFOLD_R1096 // There should have 2 messages found so the RowCount should be 2. Site.CaptureRequirementIfAreEqual<uint>( 2, getContentsTableResponse.RowCount, 1096, @"[In Processing a RopSetSearchCriteria ROP Request] For dynamic search folders, the contents of the search folder MUST continue to be updated as messages start to match or cease to match the search criteria. "); // Add the debug information Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCFOLD_R1210"); // Verify MS-OXCFOLD requirement: MS-OXCFOLD_R1210 Site.CaptureRequirementIfAreEqual<uint>( 2, getContentsTableResponse.RowCount, 1210, @"[In RopSetSearchCriteria ROP Request Buffer] SearchFlags (4 bytes): STATIC_SEARCH (0x00040000) means that the search is dynamic, if not set."); // Add the debug information Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCFOLD_R1095"); // Verify MS-OXCFOLD requirement: MS-OXCFOLD_R1095 // There should have 2 messages found so the RowCount should be 2. Site.CaptureRequirementIfAreEqual<uint>( 2, getContentsTableResponse.RowCount, 1095, @"[In Processing a RopSetSearchCriteria ROP Request] For dynamic search folders, the contents of the search folder MUST continue to be updated as messages move around the mailbox. "); // Add the debug information Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCFOLD_R1097"); // Verify MS-OXCFOLD requirement: MS-OXCFOLD_R1097 Site.CaptureRequirementIfAreEqual<uint>( 2, getContentsTableResponse.RowCount, 1097, @"[In Processing a RopSetSearchCriteria ROP Request] The server continues to update the search folder with messages that enter or exit the search criteria."); #endregion #endregion }
public void MSOXCFOLD_S04_TC04_RopMoveCopyMessagesInPublicFolderSuccess() { this.CheckWhetherSupportTransport(); this.Logon(); this.PublicFolderInitialization(); #region Step 1. The client calls RopCreateFolder to create [MSOXCFOLDSubfolder1] under the root public folder. RopCreateFolderRequest createFolderRequest = new RopCreateFolderRequest { RopId = (byte)RopId.RopCreateFolder, LogonId = Constants.CommonLogonId, InputHandleIndex = Constants.CommonInputHandleIndex, OutputHandleIndex = Constants.CommonOutputHandleIndex, FolderType = (byte)FolderType.Genericfolder, UseUnicodeStrings = 0x0, OpenExisting = 0x01, Reserved = 0x0, DisplayName = Encoding.ASCII.GetBytes(Constants.Subfolder1), Comment = Encoding.ASCII.GetBytes(Constants.Subfolder1) }; RopCreateFolderResponse createFolderResponse = this.Adapter.CreateFolder(createFolderRequest, this.publicRootFolderHandle, ref this.responseHandles); Site.Assert.AreEqual<uint>(0, createFolderResponse.ReturnValue, "RopCreateFolder ROP operation performs should successfully."); uint subfolderHandle1 = this.responseHandles[0][createFolderResponse.OutputHandleIndex]; #endregion #region Step 2. The client creates a message in the root public folder. uint messageHandle = 0; ulong messageId = 0; this.CreateSaveMessage(this.publicRootFolderHandle, this.publicRootFolderId, ref messageId, ref messageHandle); #endregion #region Step 3. The client calls RopMoveCopyMessages to copy the message from the root public folder to [MSOXCFOLDSubfolder1]. ulong[] messageIds = new ulong[] { messageId }; List<uint> handlelist = new List<uint> { this.publicRootFolderHandle, subfolderHandle1 }; RopMoveCopyMessagesRequest moveCopyMessagesRequest = new RopMoveCopyMessagesRequest { RopId = (byte)RopId.RopMoveCopyMessages, LogonId = Constants.CommonLogonId, SourceHandleIndex = 0x00, DestHandleIndex = 0x01, MessageIdCount = (ushort)messageIds.Length, MessageIds = messageIds, WantAsynchronous = 0x00, WantCopy = 0x01 }; // WantCopy is non-zero (TRUE) indicates this is a copy operation. RopMoveCopyMessagesResponse moveCopyMessagesResponse = this.Adapter.MoveCopyMessages(moveCopyMessagesRequest, handlelist, ref this.responseHandles); Site.Assert.AreEqual<uint>(0, moveCopyMessagesResponse.ReturnValue, "The RopMoveCopyMessages ROP operation performs should successfully."); handlelist.Clear(); #endregion #region Step 4. The client calls RopGetContentsTable to retrieve the contents table for [MSOXCFOLDSubfolder1] with 'ConversationMembers' flag. RopGetContentsTableRequest getContentsTableRequest = new RopGetContentsTableRequest { RopId = (byte)RopId.RopGetContentsTable, LogonId = Constants.CommonLogonId, InputHandleIndex = Constants.CommonInputHandleIndex, OutputHandleIndex = Constants.CommonOutputHandleIndex, TableFlags = (byte)FolderTableFlags.None }; RopGetContentsTableResponse getContentsTableResponse = this.Adapter.GetContentsTable(getContentsTableRequest, this.publicRootFolderHandle, ref this.responseHandles); Site.Assert.AreEqual<uint>(Constants.SuccessCode, getContentsTableResponse.ReturnValue, "RopGetContentsTable ROP operation performs should successfully."); #region Verify the requirement: MS-OXCFOLD_R14502 and MS-OXCFOLD_R10252. // Add the debug information Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCFOLD_R10252: the return value of the getContentsTableResponse is {0}", getContentsTableResponse.ReturnValue); // Verify MS-OXCFOLD requirement: MS-OXCFOLD_R10252 // The'ConversationMembers' flag is seted in the getContentsTableRequest, so if the getContentsTableResponse returns success. R10252 can be verified. Site.CaptureRequirementIfAreEqual<uint>( 0, getContentsTableResponse.ReturnValue, 10252, @"[In RopGetContentsTable ROP Request Buffer] This bit [ConversationMembers] is supported on public folders."); // Add the debug information Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCFOLD_R14502"); // Verify MS-OXCFOLD requirement: MS-OXCFOLD_R14502 Site.CaptureRequirementIfAreEqual<uint>( 1, getContentsTableResponse.RowCount, 14502, @"[In RopMoveCopyMessages ROP] This ROP applies to both public folders [and private mailboxes]."); #endregion #endregion }
public void MSOXCFOLD_S03_TC01_StaticSearchVerification() { this.CheckWhetherSupportTransport(); this.Adapter.DoConnect(ConnectionType.PrivateMailboxServer); this.GenericFolderInitialization(); #region Step 1. The client calls RopCreateFolder to create the general folder [MSOXCFOLDSubfolder1] under the root folder. RopCreateFolderRequest createFolderRequest = new RopCreateFolderRequest { RopId = (byte)RopId.RopCreateFolder, LogonId = Constants.CommonLogonId, InputHandleIndex = Constants.CommonInputHandleIndex, OutputHandleIndex = Constants.CommonOutputHandleIndex, FolderType = (byte)FolderType.Genericfolder, UseUnicodeStrings = 0x0, OpenExisting = 0x00, Reserved = 0x0, DisplayName = Encoding.ASCII.GetBytes(Constants.Subfolder1), Comment = Encoding.ASCII.GetBytes(Constants.Subfolder1) }; RopCreateFolderResponse createFolderResponse = this.Adapter.CreateFolder(createFolderRequest, this.RootFolderHandle, ref this.responseHandles); Site.Assert.AreEqual<uint>(Constants.SuccessCode, createFolderResponse.ReturnValue, "RopCreateFolder ROP operation performs successfully!"); uint subfolderHandle1 = this.responseHandles[0][createFolderResponse.OutputHandleIndex]; ulong subfolderId1 = createFolderResponse.FolderId; #endregion #region Step 2. The client creates two general messages under the folder [MSOXCFOLDSubfolder1]. uint messageHandle1 = 0; ulong messageId1 = 0; this.CreateSaveMessage(subfolderHandle1, subfolderId1, ref messageId1, ref messageHandle1); uint messageHandle2 = 0; ulong messageId2 = 0; this.CreateSaveMessage(subfolderHandle1, subfolderId1, ref messageId2, ref messageHandle2); #endregion #region Step 3. The client calls RopCreateFolder to create the search folder [MSOXCFOLDSearchFolder2] under the root folder. createFolderRequest.FolderType = (byte)FolderType.Searchfolder; createFolderRequest.DisplayName = Encoding.ASCII.GetBytes(Constants.SearchFolder2); createFolderRequest.Comment = Encoding.ASCII.GetBytes(Constants.SearchFolder2); createFolderResponse = this.Adapter.CreateFolder(createFolderRequest, this.RootFolderHandle, ref this.responseHandles); Site.Assert.AreEqual<uint>(Constants.SuccessCode, createFolderResponse.ReturnValue, "RopCreateFolder ROP operation performs successfully!"); uint searchFolderHandle2 = this.responseHandles[0][createFolderResponse.OutputHandleIndex]; #endregion #region Step 4. The client calls RopSetSearchCriteria to establish search criteria for [MSOXCFOLDSearchFolder2]. RopSetSearchCriteriaRequest setSearchCriteriaRequest = new RopSetSearchCriteriaRequest { RopId = (byte)RopId.RopSetSearchCriteria, LogonId = Constants.CommonLogonId, InputHandleIndex = Constants.CommonInputHandleIndex }; PropertyTag propertyTag = new PropertyTag { PropertyId = (ushort)MessagePropertyId.PidTagMessageClass, PropertyType = (ushort)PropertyType.PtypString }; ExistRestriction existRestriction = new ExistRestriction { PropTag = propertyTag }; setSearchCriteriaRequest.RestrictionDataSize = (ushort)existRestriction.Size(); setSearchCriteriaRequest.RestrictionData = existRestriction.Serialize(); setSearchCriteriaRequest.FolderIds = new ulong[] { subfolderId1 }; setSearchCriteriaRequest.FolderIdCount = (ushort)setSearchCriteriaRequest.FolderIds.Length; setSearchCriteriaRequest.SearchFlags = (uint)SetSearchFlags.ContentIndexedSearch | (uint)SetSearchFlags.StaticSearch | (uint)SetSearchFlags.RestartSearch; RopSetSearchCriteriaResponse setSearchCriteriaResponse = this.Adapter.SetSearchCriteria(setSearchCriteriaRequest, searchFolderHandle2, ref this.responseHandles); Site.Assert.AreEqual<uint>(Constants.SuccessCode, setSearchCriteriaResponse.ReturnValue, "RopSearchCriteria ROP operation performs successfully!"); #endregion #region Step 5. The client calls RopGetSearchCriteria to obtain the search criteria and the status of the search folder [MSOXCFOLDSearchFolder2]. RopGetSearchCriteriaRequest getSearchCriteriaRequest = new RopGetSearchCriteriaRequest { RopId = (byte)RopId.RopGetSearchCriteria, LogonId = Constants.CommonLogonId, InputHandleIndex = Constants.CommonInputHandleIndex, UseUnicode = 0x00, IncludeRestriction = 0x01, IncludeFolders = 0x01 }; RopGetSearchCriteriaResponse getSearchCriteriaResponse = this.Adapter.GetSearchCriteria(getSearchCriteriaRequest, searchFolderHandle2, ref this.responseHandles); Site.Assert.AreEqual<uint>(Constants.SuccessCode, getSearchCriteriaResponse.ReturnValue, "RopGetSearchCriteria ROP operation performs successfully!"); #region Verify the requirements: MS-OXCFOLD_R1200 and MS-OXCFOLD_R1233. // Add the debug information Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCFOLD_R1200"); // Verify MS-OXCFOLD requirement: MS-OXCFOLD_R1200 // SHALLOW_SEARCH bit in the RopSetSearchCriteria ROP request means the search includes only the search folder containers that are specified in the FolderIds field. // If the bit SEARCH_RECURSIVE in the RopGetSearchCriteria ROP response is not set means only the search folder containers that are specified in the last RopSetSearchCriteria ROP request are being searched. // So, if the bit SEARCH_RECURSIVE in getSearchCriteriaResponse is not set, R1200 can be verified. Site.CaptureRequirementIfAreNotEqual<uint>( (uint)GetSearchFlags.Recursive, getSearchCriteriaResponse.SearchFlags & (uint)GetSearchFlags.Recursive, 1200, @"[In RopSetSearchCriteria ROP Request Buffer] SearchFlags (4 bytes): If neither bit [RECURSIVE_SEARCH or SHALLOW_SEARCH] is set, the default is SHALLOW_SEARCH."); // Add the debug information this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCFOLD_R1233"); List<ulong> folderIdsInGetSearchCriteriaResponse = new List<ulong>(); folderIdsInGetSearchCriteriaResponse.AddRange(getSearchCriteriaResponse.FolderIds); // Verify MS-OXCFOLD requirement: MS-OXCFOLD_R1233 this.Site.CaptureRequirementIfIsFalse( folderIdsInGetSearchCriteriaResponse.Contains(createFolderResponse.FolderId), 1233, @"[In Setting Up a Search Folder] [A search folder cannot be included in its own search scope] Therefore, the FolderIds field MUST NOT include the FID of the search folder."); #endregion #endregion #region Step 6. The client calls RopGetContentsTable to retrieve the contents table for the search folder [MSOXCFOLDSearchFolder2]. RopGetContentsTableRequest getContentsTableRequest = new RopGetContentsTableRequest(); RopGetContentsTableResponse getContentsTableResponse; getContentsTableRequest.RopId = (byte)RopId.RopGetContentsTable; getContentsTableRequest.LogonId = Constants.CommonLogonId; getContentsTableRequest.InputHandleIndex = Constants.CommonInputHandleIndex; getContentsTableRequest.OutputHandleIndex = Constants.CommonOutputHandleIndex; getContentsTableRequest.TableFlags = (byte)FolderTableFlags.None; int count = 0; do { getContentsTableResponse = this.Adapter.GetContentsTable(getContentsTableRequest, searchFolderHandle2, ref this.responseHandles); Site.Assert.AreEqual<uint>(Constants.SuccessCode, getContentsTableResponse.ReturnValue, "RopGetContentsTable ROP operation performs successfully!"); if (getContentsTableResponse.RowCount != 2) { Thread.Sleep(this.WaitTime); } else { break; } count++; } while (count < this.RetryCount); uint rowCountBeforeHardDel = getContentsTableResponse.RowCount; Site.Assert.AreEqual<uint>(2, rowCountBeforeHardDel, "The two general messages created in step 2 were fetched in search folder."); #endregion #region Step 7. The client calls RopHardDeleteMessage ROP operation to hard delete a message in the general folder [MSOXCFOLDSubfolder1] under the root folder. ulong[] messageIds = new ulong[] { messageId1 }; RopHardDeleteMessagesRequest hardDeleteMessagesRequest = new RopHardDeleteMessagesRequest { RopId = (byte)RopId.RopHardDeleteMessages, LogonId = Constants.CommonLogonId, InputHandleIndex = Constants.CommonInputHandleIndex, WantAsynchronous = 0x00, NotifyNonRead = 0x00, MessageIdCount = (ushort)messageIds.Length, MessageIds = messageIds }; RopHardDeleteMessagesResponse hardDeleteMessagesResponse = this.Adapter.HardDeleteMessages(hardDeleteMessagesRequest, subfolderHandle1, ref this.responseHandles); Site.Assert.AreEqual<uint>(Constants.SuccessCode, hardDeleteMessagesResponse.ReturnValue, "RopHardDeleteMessages ROP operation performs successfully!"); Site.Assert.AreEqual<uint>(0x00, hardDeleteMessagesResponse.PartialCompletion, "RopHardDeleteMessages ROP operation is complete!"); #endregion #region Step 8. The client calls RopGetContentsTable to retrieve the contents table for the search folder [MSOXCFOLDSearchFolder2]. count = 0; bool searchFolderNotChange = false; do { getContentsTableResponse = this.Adapter.GetContentsTable(getContentsTableRequest, searchFolderHandle2, ref this.responseHandles); Site.Assert.AreEqual<uint>(Constants.SuccessCode, getContentsTableResponse.ReturnValue, "RopGetContentsTable ROP operation performs successfully!"); if (getContentsTableResponse.RowCount != rowCountBeforeHardDel) { Thread.Sleep(this.WaitTime); } else { searchFolderNotChange = true; break; } count++; } while (count < this.RetryCount); #region Verify the requirements: MS-OXCFOLD_R795, MS-OXCFOLD_R784, MS-OXCFOLD_R1084, MS-OXCFOLD_R549, MS-OXCFOLD_R1093, MS-OXCFOLD_R1094. // Add the debug information Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCFOLD_R795"); // Verify MS-OXCFOLD requirement: MS-OXCFOLD_R795 // The search folder contents didn't change after the message has been hard deleted, it indicates the current search is static search. Site.CaptureRequirementIfIsTrue( searchFolderNotChange, 795, @"[In RopGetSearchCriteria ROP Response Buffer] SearchFlags (4 bytes): SEARCH_STATIC (0x00010000) means that the search is static."); // Add the debug information Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCFOLD_R784"); // Verify MS-OXCFOLD requirement: MS-OXCFOLD_R784 Site.CaptureRequirementIfIsTrue( searchFolderNotChange, 784, @"[In RopSetSearchCriteria ROP Request Buffer] SearchFlags (4 bytes): STATIC_SEARCH (0x00040000) means that the search is static, if set."); // Add the debug information Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCFOLD_R1084"); // Verify MS-OXCFOLD requirement: MS-OXCFOLD_R1084 Site.CaptureRequirementIfIsTrue( searchFolderNotChange, 1084, @"[In Processing a RopSetSearchCriteria ROP Request] For static search folders, the contents of the search folder are not updated after the initial population is complete."); // Add the debug information Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCFOLD_R549"); // Verify MS-OXCFOLD requirement: MS-OXCFOLD_R549 Site.CaptureRequirementIfIsTrue( searchFolderNotChange, 549, @"[In Processing a RopSetSearchCriteria ROP Request] A static search causes the search folder to be populated once with all messages that match the search criteria at the point in time when the search is started or restarted."); // Add the debug information Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCFOLD_R1093"); // Verify MS-OXCFOLD requirement: MS-OXCFOLD_R1093 Site.CaptureRequirementIfIsTrue( searchFolderNotChange, 1093, @"[In Processing a RopSetSearchCriteria ROP Request] The server MUST NOT update the search folder after the initial population when new messages that match the search criteria arrive in the search scope."); // Add the debug information Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCFOLD_R1094"); // Verify MS-OXCFOLD requirement: MS-OXCFOLD_R1094 Site.CaptureRequirementIfIsTrue( searchFolderNotChange, 1094, @"[In Processing a RopSetSearchCriteria ROP Request] Or the server MUST NOT update the search folder after the initial population when existing messages that fit the search criteria are deleted."); #endregion #endregion #region Step 9. The client calls RopSetSearchCriteria to restart the search for [MSOXCFOLDSearchFolder2]. setSearchCriteriaRequest.SearchFlags = (uint)SetSearchFlags.ContentIndexedSearch | (uint)SetSearchFlags.RestartSearch; setSearchCriteriaResponse = this.Adapter.SetSearchCriteria(setSearchCriteriaRequest, searchFolderHandle2, ref this.responseHandles); Site.Assert.AreEqual<uint>(Constants.SuccessCode, setSearchCriteriaResponse.ReturnValue, "RopSearchCriteria ROP operation performs successfully!"); #endregion #region Step 10. The client calls RopGetContentsTable to retrieve the contents table for the search folder [MSOXCFOLDSearchFolder2]. count = 0; do { getContentsTableResponse = this.Adapter.GetContentsTable(getContentsTableRequest, searchFolderHandle2, ref this.responseHandles); Site.Assert.AreEqual<uint>(Constants.SuccessCode, getContentsTableResponse.ReturnValue, "RopGetContentsTable ROP operation performs successfully!"); if (getContentsTableResponse.RowCount != 1) { Thread.Sleep(this.WaitTime); } else { break; } count++; } while (count < this.RetryCount); // Add the debug information Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCFOLD_R551"); // Verify MS-OXCFOLD requirement: MS-OXCFOLD_R551 // There should be 1 message found and copy to the search folder, so the RowCount should be 1. Site.CaptureRequirementIfAreEqual<uint>( 1, getContentsTableResponse.RowCount, 551, @"[In Processing a RopSetSearchCriteria ROP Request] To trigger an update, another RopSetSearchCriteria ROP request with the RESTART_SEARCH bit set in the SearchFlags field, as specified in section 2.2.1.4.1, is required."); #endregion #region Step 11. The client calls RopSetSearchCriteria to establish search criteria for [MSOXCFOLDSearchFolder2] by a new RestrictionData. setSearchCriteriaRequest = new RopSetSearchCriteriaRequest(); setSearchCriteriaRequest.RopId = (byte)RopId.RopSetSearchCriteria; setSearchCriteriaRequest.LogonId = Constants.CommonLogonId; setSearchCriteriaRequest.InputHandleIndex = Constants.CommonInputHandleIndex; ContentRestriction contentRestriction = new ContentRestriction { FuzzyLevelLow = FuzzyLevelLowValues.FL_PREFIX, FuzzyLevelHigh = FuzzyLevelHighValues.FL_IGNORECASE }; propertyTag = new PropertyTag { PropertyId = (ushort)MessagePropertyId.PidTagMessageClass, PropertyType = (ushort)PropertyType.PtypString }; contentRestriction.PropertyTag = propertyTag; TaggedPropertyValue taggedProperty = new TaggedPropertyValue { PropertyTag = propertyTag, Value = Encoding.Unicode.GetBytes("IPM.Task" + Constants.StringNullTerminated) }; contentRestriction.TaggedValue = taggedProperty; setSearchCriteriaRequest.RestrictionDataSize = (ushort)contentRestriction.Size(); setSearchCriteriaRequest.RestrictionData = contentRestriction.Serialize(); setSearchCriteriaRequest.FolderIds = new ulong[] { subfolderId1 }; setSearchCriteriaRequest.FolderIdCount = (ushort)setSearchCriteriaRequest.FolderIds.Length; setSearchCriteriaRequest.SearchFlags = (uint)SetSearchFlags.ContentIndexedSearch | (uint)SetSearchFlags.RestartSearch | (uint)SetSearchFlags.StaticSearch; setSearchCriteriaResponse = this.Adapter.SetSearchCriteria(setSearchCriteriaRequest, searchFolderHandle2, ref this.responseHandles); Site.Assert.AreEqual<uint>(Constants.SuccessCode, setSearchCriteriaResponse.ReturnValue, "RopSearchCriteria ROP operation performs successfully!"); #endregion #region Step 12. The client calls RopGetContentsTable to retrieve the contents table for the search folder [MSOXCFOLDSearchFolder2]. count = 0; do { getContentsTableResponse = this.Adapter.GetContentsTable(getContentsTableRequest, searchFolderHandle2, ref this.responseHandles); Site.Assert.AreEqual<uint>(Constants.SuccessCode, getContentsTableResponse.ReturnValue, "RopGetContentsTable ROP operation performs successfully!"); if (getContentsTableResponse.RowCount != 0) { Thread.Sleep(this.WaitTime); } else { break; } count++; } while (count < this.RetryCount); // Add the debug information Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCFOLD_R519"); // Verify MS-OXCFOLD requirement: MS-OXCFOLD_R519 // For no message should be found so the search folder should empty, which means the RowCount is 0. Site.CaptureRequirementIfAreEqual<uint>( 0, getContentsTableResponse.RowCount, 519, @"[In Processing a RopSetSearchCriteria ROP Request] When new search criteria are applied, the server modifies the search folder to include only the messages that match the new search criteria."); #endregion }
public void MSOXCFOLD_S04_TC07_RopEmptyPublicFolder() { if (!Common.IsRequirementEnabled(97501002, this.Site)) { this.NeedCleanup = false; Site.Assert.Inconclusive("The server does not support the RopEmptyFolder ROP ([MS-OXCROPS] section 2.2.4.9) for public folders."); } this.CheckWhetherSupportTransport(); this.Logon(); this.PublicFolderInitialization(); #region Step 1. The client calls RopCreateFolder to create [MSOXCFOLDSubfolder1] under the root public folder. RopCreateFolderRequest createFolderRequest = new RopCreateFolderRequest { RopId = (byte)RopId.RopCreateFolder, LogonId = Constants.CommonLogonId, InputHandleIndex = Constants.CommonInputHandleIndex, OutputHandleIndex = Constants.CommonOutputHandleIndex, FolderType = (byte)FolderType.Genericfolder, UseUnicodeStrings = 0x0, OpenExisting = 0x01, Reserved = 0x0, DisplayName = Encoding.ASCII.GetBytes(Constants.Subfolder1), Comment = Encoding.ASCII.GetBytes(Constants.Subfolder1) }; RopCreateFolderResponse createFolderResponse = this.Adapter.CreateFolder(createFolderRequest, this.publicRootFolderHandle, ref this.responseHandles); Site.Assert.AreEqual<uint>(0, createFolderResponse.ReturnValue, "RopCreateFolder ROP operation performs successfully."); uint subfolderHandle1 = this.responseHandles[0][createFolderResponse.OutputHandleIndex]; #endregion #region Step 2. The client creates a message in [MSOXCFOLDSubfolder1]. uint messageHandle = 0; ulong messageId = 0; this.CreateSaveMessage(this.publicRootFolderHandle, this.publicRootFolderId, ref messageId, ref messageHandle); #endregion #region Step 3. The client creates a subfolder in [MSOXCFOLDSubfolder1]. createFolderRequest.DisplayName = Encoding.ASCII.GetBytes(Constants.Subfolder2); createFolderRequest.Comment = Encoding.ASCII.GetBytes(Constants.Subfolder2); createFolderResponse = this.Adapter.CreateFolder(createFolderRequest, subfolderHandle1, ref this.responseHandles); Site.Assert.AreEqual<uint>(0, createFolderResponse.ReturnValue, "RopCreateFolder ROP operation performs successfully."); #endregion #region Step 4. The client calls RopEmptyFolder to empty [MSOXCFOLDSubfolder1]. RopEmptyFolderRequest emptyFolderRequest = new RopEmptyFolderRequest { RopId = (byte)RopId.RopEmptyFolder, LogonId = Constants.CommonLogonId, InputHandleIndex = Constants.CommonInputHandleIndex, WantAsynchronous = 0x00, WantDeleteAssociated = 0x00 }; // Invoke RopEmptyFolder operation to soft delete Subfolder3 from Subfolder1 without deleting Subfolder1. RopEmptyFolderResponse emptyFolderResponse = this.Adapter.EmptyFolder(emptyFolderRequest, subfolderHandle1, ref this.responseHandles); Site.Assert.AreEqual<uint>(0, emptyFolderResponse.ReturnValue, "RopEmptyFolder ROP operation performs successfully on [MSOXCFOLDSubfolder1]."); #endregion #region Step 5. The client calls RopGetContentsTable to retrieve the contents table of [MSOXCFOLDSubfolder1]. RopGetContentsTableRequest getContentsTableRequest = new RopGetContentsTableRequest { RopId = (byte)RopId.RopGetContentsTable, LogonId = Constants.CommonLogonId, InputHandleIndex = Constants.CommonInputHandleIndex, OutputHandleIndex = Constants.CommonOutputHandleIndex, TableFlags = (byte)FolderTableFlags.None }; RopGetContentsTableResponse getContentsTableResponse = this.Adapter.GetContentsTable(getContentsTableRequest, subfolderHandle1, ref this.responseHandles); Site.Assert.AreEqual<uint>(Constants.SuccessCode, getContentsTableResponse.ReturnValue, "RopGetContentsTable ROP operation performs successfully!"); #endregion #region Step 6. The client calls RopGetHierarchyTable to retrieve the hierarchy table of [MSOXCFOLDSubfolder1]. RopGetHierarchyTableRequest getHierarchyTableRequest = new RopGetHierarchyTableRequest { RopId = (byte)RopId.RopGetHierarchyTable, LogonId = Constants.CommonLogonId, InputHandleIndex = Constants.CommonInputHandleIndex, OutputHandleIndex = Constants.CommonOutputHandleIndex, TableFlags = (byte)FolderTableFlags.None }; RopGetHierarchyTableResponse getHierarchyTableResponse = this.Adapter.GetHierarchyTable(getHierarchyTableRequest, subfolderHandle1, ref this.responseHandles); Site.Assert.AreEqual<uint>(Constants.SuccessCode, getHierarchyTableResponse.ReturnValue, "RopGetHierarchyTable ROP operation performs successfully!"); // Add the debug information Site.Log.Add( LogEntryKind.Debug, "Verify MS-OXCFOLD_R97501002: The message count of the target folder after RopEmptyFolder is {0}, the subfolder count of the target folder after RopEmptyFolder is {1}", getContentsTableResponse.RowCount, getHierarchyTableResponse.RowCount); bool isVerifyR97501002 = getContentsTableResponse.RowCount == 0 && getHierarchyTableResponse.RowCount == 0; // Verify MS-OXCFOLD requirement: MS-OXCFOLD_R97501002. Site.CaptureRequirementIfIsTrue( isVerifyR97501002, 97501002, @"[In Appendix A: Product Behavior] Implementation does support the RopEmptyFolder ROP ([MS-OXCROPS] section 2.2.4.9) for public folders. (Microsoft Exchange Server 2007 and Microsoft Exchange Server 2010 follow this behavior.)"); #endregion }
/// <summary> /// Get row count of a specified folder's contents table. /// </summary> /// <param name="flags">The TableFlags parameter contains a bitmask of flags that control how information is returned in the table on folder.</param> /// <param name="inputHandle">The folder object handle.</param> /// <returns>Row count of the specified folder's contents table.</returns> protected uint GetContentsTable(FolderTableFlags flags, uint inputHandle) { RopGetContentsTableRequest request = new RopGetContentsTableRequest { RopId = (byte)RopId.RopGetContentsTable, LogonId = Constants.CommonLogonId, InputHandleIndex = Constants.CommonInputHandleIndex, OutputHandleIndex = Constants.CommonOutputHandleIndex, TableFlags = (byte)flags }; RopGetContentsTableResponse response = this.Adapter.GetContentsTable(request, inputHandle, ref this.responseHandles); return response.RowCount; }
/// <summary> /// Get the content table of specific folder. /// </summary> /// <param name="objHandle">The handle of specific folder.</param> /// <returns>The handle of content table.</returns> protected RopGetContentsTableResponse GetContentTableSuccess(uint objHandle) { RopGetContentsTableRequest getContentsTableRequest = new RopGetContentsTableRequest() { RopId = (byte)RopId.RopGetContentsTable, LogonId = CommonLogonId, InputHandleIndex = CommonInputHandleIndex, OutputHandleIndex = CommonOutputHandleIndex, TableFlags = (byte)FolderTableFlags.None }; this.ResponseSOHs = this.MSOXCMSGAdapter.DoRopCall(getContentsTableRequest, objHandle, ref this.response, ref this.rawData, GetPropertiesFlags.None); RopGetContentsTableResponse getContentsTableResponse = (RopGetContentsTableResponse)this.response; Site.Assert.AreEqual<uint>(TestSuiteBase.Success, getContentsTableResponse.ReturnValue, TestSuiteBase.ROPSucceedMsg); return getContentsTableResponse; }